onCreate() 被调用而不是 onActivityResult()
onCreate() gets called instead of onActivityResult()
所以我在浏览器中使用 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
在 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>
首先,您使用
启动浏览器
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivityForResult(intent, 1);
此意图不会return任何结果。它只要求浏览器显示 url。所以浏览器不会 returning 任何结果。
但是,在身份验证之后,浏览器会触发一个意图并请求一个新的 LoginActivity 实例。当然会调用 onCreate()
就像 LoginActivity(#1) -> Browser -> LoginActivity(#2)
您可以在 onCreate() 中调用这部分代码,它将起作用:
Uri uri = getIntent().getData();
String code = uri.getQueryParameter("code");
Log.d("called",code);
但是两个不同的意图(启动器和 action_view)可以出于两个不同的目的达到相同的 activity。你最好创建两个不同的活动。首先是您常用的 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);
}
}
}
}
所以我在浏览器中使用 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
在 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>
首先,您使用
启动浏览器Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivityForResult(intent, 1);
此意图不会return任何结果。它只要求浏览器显示 url。所以浏览器不会 returning 任何结果。 但是,在身份验证之后,浏览器会触发一个意图并请求一个新的 LoginActivity 实例。当然会调用 onCreate()
就像 LoginActivity(#1) -> Browser -> LoginActivity(#2)
您可以在 onCreate() 中调用这部分代码,它将起作用:
Uri uri = getIntent().getData();
String code = uri.getQueryParameter("code");
Log.d("called",code);
但是两个不同的意图(启动器和 action_view)可以出于两个不同的目的达到相同的 activity。你最好创建两个不同的活动。首先是您常用的 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);
}
}
}
}