Android 浏览器意图并返回到正确的活动(关闭打开的选项卡)
在Android中实现Android 浏览器意图并返回到正确的活动(关闭打开的选项卡),android,google-chrome,android-intent,oauth-2.0,Android,Google Chrome,Android Intent,Oauth 2.0,在Android中实现AccountManager中的自定义帐户类型时,我的登录流存在以下问题: 登录应该通过OAuth提供程序进行。因此,我创建了一个SignInActivity,它启动一个WebView,并启动一个OAuth流。当接收到对my custom的回调时,这可以正常工作-scheme://callbackWebView检测它,接收codequerystring参数并完成流程。使用WebView的缺点是,即使用户可能已经在浏览器中有一个活动会话,但该会话不会在WebView中使用,因
AccountManager
中的自定义帐户类型时,我的登录流存在以下问题:
登录应该通过OAuth提供程序进行。因此,我创建了一个SignInActivity
,它启动一个WebView
,并启动一个OAuth流。当接收到对my custom的回调时,这可以正常工作-scheme://callback
WebView检测它,接收code
querystring参数并完成流程。使用WebView
的缺点是,即使用户可能已经在浏览器中有一个活动会话,但该会话不会在WebView
中使用,因此用户必须再次登录WebView
为了解决这个问题,我尝试在AndroidManifest.xml
中使用intent过滤器,如下所示:
<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:scheme="my-custom-scheme" android:path="callback"/>
</intent-filter>
在mySignenActivity
中,我有以下代码来处理回调:
if (intent != null && intent.getData() != null && getString("my-custom-scheme").equals(intent.getData().getScheme())) {
String code = getIntent().getData().getQueryParameter("code");
// complete oauth flow
}
这很有效。但是,要解决这个问题(最后!):
如果用户未登录,浏览器意图将显示oauth提供程序的登录页面。用户登录后,Chrome将重定向到my custom-scheme://callback 而signalivity
将启动以处理意图。由于此活动不可见,因此浏览器将在登录页面上保持打开状态,对用户而言,它看起来就像什么都没有发生。浏览器永远不会关闭
如果用户已经登录,oauth提供程序将直接重定向到my custom-scheme://callback. 在这种情况下,浏览器选项卡将自动关闭,但浏览器本身保持打开状态(没有可见的选项卡)
所以我的问题是:在重定向到我的自定义浏览器后,是否有任何方法可以使浏览器的行为有所不同-scheme://callback? 理想情况下,我希望它在重定向到回调后简单地关闭,并返回到活动堆栈中的上一个活动(即从一开始启动重要活动的活动)。我使用了下一种方法来解决相同的问题
假设我们有MainActivity
和登录按钮而不是直接点击该按钮启动浏览器,我使用startActivityForResult
方法启动SignInActivity
。它的使用,然后我可以处理登录流的结果
startActivityForResult(新意图(this,SignInActivity.class),requestCode)代码>
重要性
负责:
- 使用登录页面打开浏览器
- 捕获重定向到
自定义-scheme://callback
- 使用从重定向url接收的令牌完成登录流
- 将结果返回到
MainActivity
因此,其onCreate
方法如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
if (intent != null && intent.getData() != null && "custom-scheme".equals(intent.getData().getScheme())) {
String code = getIntent().getData().getQueryParameter("code");
// complete oauth flow
} else {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, "http://oauth2provider/authorize")
.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
startActivity(browserIntent);
finish();
}
}
允许在浏览器中设置标志
这样,如果从MainActivity
打开SignInActivity
,它只会在浏览器中打开登录页面,如果打开该页面捕获重定向url,它将完成登录流并发送相应的请求
完成登录流并将代码发送到回调方法中的某个端点后,应执行以下操作:
setResult(Activity.RESULT_OK);
this.finish();
当然,您将从该端点接收访问令牌。您可以将其存储在此处的某个位置,即成功回调中,或者将其返回到main活动
,以便在此处进行处理
作为signianctivity
的布局,您只需在页面中央使用ProgressBar
。它将在登录流完成期间,在打开重定向url(custom)后显示SignInActivity
-scheme://callback
)
这对我没有帮助
setResult(Activity.RESULT_OK);
this.finish();
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ProgressBar
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
<activity android:name=".SignInActivity"
android:launchMode="singleTask"
android:noHistory="true"
>
<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:scheme="custom-scheme" android:host="callback"/>
</intent-filter>
</activity>