Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 浏览器意图并返回到正确的活动(关闭打开的选项卡)_Android_Google Chrome_Android Intent_Oauth 2.0 - Fatal编程技术网

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中使用,因

在Android中实现
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>
在my
SignenActivity
中,我有以下代码来处理回调:

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>