【问题标题】:onCreate() gets called instead of onActivityResult()onCreate() 被调用而不是 onActivityResult()
【发布时间】:2018-06-14 06:56:18
【问题描述】:

所以我使用浏览器中的 OAuth 通过 GitHub 帐户对用户进行身份验证。但是在我从LoginActivity 触发Intent 之后,onResume() 在用户打开浏览器之前执行,因此返回uri 的值等于null

这里是LoginActivity

public class LoginActivity extends AppCompatActivity {

    Button loginButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        loginButton = findViewById(R.id.button);
        final String url = "oauth url...";
        Log.d("called","oncreate");
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("called","onclick");
                attemptLogin(url);
            }
        });
    }

    private void attemptLogin(String url){
        Log.d("called","onattempt");
        Intent intent = new Intent(this, BrowserActivity.class);
        intent.putExtra("URL", url);
        startActivityForResult(intent, 1);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Uri uri = data.getData();
        String code = uri.getQueryParameter("code");
        Log.d("called",code);
    }
}

BrowserActivity:

public class BrowserActivity extends AppCompatActivity {

    public static String CALLBACK_URL = "callback url..";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_browser);
        Intent intent = getIntent();
        if(intent != null){
            String url = intent.getStringExtra("URL");
            Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(i);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Uri uri = getIntent().getData();
        if(uri != null && uri.toString().startsWith(CALLBACK_URL)) {
            String code = uri.getQueryParameter("code");
            Intent intent = new Intent();
            intent.putExtra("code",code);
            setResult(RESULT_OK, intent);
            finish();
        }
    }
}

LoginActivity in AndroidManifest.xml:

<activity
    android:name=".ui.activities.LoginActivity"
    android:label="@string/app_name"
    android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name=".ui.activities.BrowserActivity"
          android:label="@string/app_name"
          android:theme="@style/AppTheme.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data
            android:host="callback"
            android:scheme="app"
            />
    </intent-filter>
</activity>

【问题讨论】:

  • 正常。您的回调只是根据您的清单重新启动 LoginActivity。
  • 但它不应该执行onActivityResult()吗? @FrançoisL.
  • 不行,你必须创建一个专门的Activity来拦截回调。
  • 试过这样做。但是在浏览器甚至从onCreate()@FrançoisL 开始之前,onResult() 就被调用了。
  • "但它不应该执行 onActivityResult() 吗?" -- 是的,但这可能发生在onCreate() 之后,如果您的进程在浏览器处于前台时终止。另外,ACTION_VIEW 不会返回结果,因此您在onActivityResult() 中的代码似乎毫无用处。

标签: android github github-api


【解决方案1】:

首先,使用

启动浏览器
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    startActivityForResult(intent, 1);

此意图不返回任何结果。它只要求浏览器显示 url。所以浏览器不会返回任何结果。 然而,在认证之后,浏览器会触发一个意图并请求一个新的 LoginActivity 实例。当然会调用 onCreate()

就像 LoginActivity(#1) -> Browser -> LoginActivity(#2)

您可以在 onCreate() 中调用这部分代码,它会起作用:

Uri uri = getIntent().getData();
String code = uri.getQueryParameter("code");
Log.d("called",code);

但是两个不同的意图(launcher 和 action_view)可以针对两个不同的目的达到同一个活动。你最好创建两个不同的活动。首先是您通常的 LoginActivity 和第二个(继承自第一个)BrowserActivity,它重新定义了 onCreate。到目前为止,您的清单看起来像

<activity
android:name=".ui.activities.LoginActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activities.BrowserActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data
        android:host="callback"
        android:scheme="app"
        />
</intent-filter>
</activity>

LoginActivity 代码应如下所示:

public class LoginActivity extends AppCompatActivity {

Button loginButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    loginButton = findViewById(R.id.button);
    final String url = "oauth url...";
    Log.d("called","oncreate");
    loginButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("called","onclick");
            attemptLogin(url);
        }
    });
}

private void attemptLogin(String url){
    Log.d("called","onattempt");

        // open the browser with url

        Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(i);
}

// no onResult 

}

这是 BrowserActivityCode:

public class BrowserActivity extends LoginActivity {

// this will be triggered after authentification
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    processIntent();
}


protected void processIntent() {
    Intent intentFromBrowser = getIntent();
    if (intentFromBrowser != null) {
        Uri uri = intentFromBrowser.getData();
    if(uri != null && uri.toString().startsWith(CALLBACK_URL)) {
        String code = uri.getQueryParameter("code");
        Log.d("code value", code);
    }
    }
}
}

【讨论】:

  • 即使按照您的方法,我也面临一些问题。我已经用同样的方法更新了这个问题。请看一看。
  • 你能弄清楚吗?
  • 请问您是否还没有将意图从LoginActivity 传递给BrowserActivity,您如何检索一个?您直接调用ACTION_VIEW 意图。
  • 浏览器将该意图传递给 BrowserActivity
  • 酷。我不知道。如果我想将代码发回LoginActivity 怎么办?请不要更改此答案,而是通过 pastebin.com 或其他方式粘贴。另外,如果我想联系你,我该怎么做?我真的很感谢你,将来可能需要你的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
相关资源
最近更新 更多