在Android中的AccountManager
中实施自定义帐户类型时,我对登录流程存在以下问题:
登录应通过OAuth提供商进行。因此,我创建了一个SignInActivity
来启动WebView
并启动OAuth流程。这工作正常,当收到my-custom-scheme://callback
WebView
的回调时,code
检测到它,接收WebView
querystring参数并完成流程。使用WebView
的缺点是,即使用户可能已在浏览器中拥有活动会话,WebView
中也不会使用此会话,因此用户必须再次登录intent-filter
1}}。
要解决此问题,我尝试使用AndroidManifest.xml
中的<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>
切换,如下所示:
WebView
我没有在SignInActivity
中打开my-custom-scheme://callback
,而是启动浏览器意图并等待浏览器点击Intent browserIntent = new Intent(Intent.ACTION_VIEW, "http://oauth2provider/authorize");
startActivity(browserIntent);
finish();
。
SignInActivity
在我的if (intent != null && intent.getData() != null && getString("my-custom-scheme").equals(intent.getData().getScheme())) {
String code = getIntent().getData().getQueryParameter("code");
// complete oauth flow
}
中,我有以下代码来处理回调:
SignInActivity
这很有效。但是,解决问题(最后!):
SignInActivity
将启动以处理意图。由于此活动不可见,浏览器将在登录页面上保持打开状态,对于用户来说,它看起来似乎什么也没发生。浏览器永远不会关闭。所以我的问题是:无论如何,在重定向到my-custom-scheme://回调后,浏览器的行为是否有所不同?理想情况下,我希望它在重定向到回调之后简单地关闭,并返回到活动堆栈中的上一个活动(即从开头开始{{1}}的活动)。
答案 0 :(得分:4)
我使用下一种方法来解决同样的问题。
假设我们MainActivity
带有Sign In
按钮。 相反启动浏览器直接点击该按钮我使用SignInActivity
方法启动startActivityForResult
。它用于那时我可以处理登录流程的结果。
startActivityForResult(new Intent(this, SignInActivity.class), requestCode);
SignInActivity
负责:
custom-scheme://callback
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();
}
}
允许将标记设置到浏览器意图中。
这样,如果从SignInActivity
打开MainActivity
,它只会在浏览器中打开登录页面,如果它已打开捕获重定向网址,则会完成登录流程,发送相应的请求。
完成登录流程后,将代码发送到回调方法中的某个端点,您应该执行以下操作:
setResult(Activity.RESULT_OK);
this.finish();
当然,您从该端点接收access_token。您可以将它存储在此处,成功回调中,或者将其返回到MainActivity
以在那里处理它。
作为SignInActivity
的布局,您只能在页面中心使用ProgressBar
。在SignInActivity
打开后,在登录流程完成时,它会显示为捕获重定向网址(custom-scheme://callback
)。
<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>
以下是SignInActivity
AndroidManifest.xml
的声明
<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>