Chrome 自定义标签重定向到 Android 应用程序将关闭该应用程序

Posted

技术标签:

【中文标题】Chrome 自定义标签重定向到 Android 应用程序将关闭该应用程序【英文标题】:Chrome Custom Tabs redirect to Android app will close the app 【发布时间】:2016-07-05 05:24:41 【问题描述】:

我正在尝试使用 android Chrome 自定义选项卡实现 OAuth2 流程,但是当 Chrome 自定义选项卡收到带有我的应用程序位置/方案的 302 时,我的应用程序总是关闭(没有崩溃)。

如果我创建一个带有 ahref 链接的 html 页面并手动触摸它,Chrome 自定义选项卡会正确切换到我的应用程序。

似乎在 Chrome 自定义选项卡中处理服务器 302 重定向时,它无法正确处理我的自定义应用方案...但是为什么呢?

如果我在股票浏览器或 WebView 中尝试相同的重定向 URL,一切正常。

这是我目前的设置:

MainActiviy.java

    Button btnChromeCustomTab = (Button) findViewById(R.id.btnChromeCustomTab);
    btnChromeCustomTab.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
            String packageName = CustomTabsHelper.getPackageNameToUse(MainActivity.this);
            customTabsIntent.intent.setPackage(packageName);
            Uri theLocationUri = Uri.parse(URL);
            customTabsIntent.launchUrl(MainActivity.this, theLocationUri);
        
    );

AndroidManifest.xml

    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter android:label="@string/filter_title">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="myappscheme" android:host="oauth" />
        </intent-filter>
    </activity>

这是应用收到的带有 HTTP 302 代码的重定向 URL:

myappscheme://oauth?code=1234567&state=tokenCheck123

build.gradle

android 
compileSdkVersion 23
buildToolsVersion "23.0.2"

defaultConfig 
    applicationId "de.myapptest.webviewtest"
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"


dependencies 
   compile fileTree(dir: 'libs', include: ['*.jar'])
   testCompile 'junit:junit:4.12'
   compile 'com.android.support:appcompat-v7:23.2.1'
   compile 'com.android.support:design:23.2.1'
   compile 'com.android.support:customtabs:23.0.0+'

感谢您的帮助...

【问题讨论】:

据我了解,您的应用程序已恢复然后关闭,对吗? logcat上是否有任何相关消息?另外,你能发布 MainActivity.java 代码吗? 只是为了记录,我刚刚使用 webview 测试了重定向(302)到自定义方案(myappscheme://...),但它不起作用。它说“未知方案”。 【参考方案1】:

我还观察到我的 Android 应用程序在服务器端 302 重定向到自定义方案后意外后台,并观察到来自独立 Chrome 的预期处理和客户端中手动触发的重定向。

我能够通过在加载重定向的 url 之前调用 warmup 函数来“修复”该问题。

换句话说,这是可行的:

void launchTab(Context context, Uri uri)
    final CustomTabsServiceConnection connection = new CustomTabsServiceConnection() 
        @Override
        public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient client) 
            final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
            final CustomTabsIntent intent = builder.build();
            client.warmup(0L); // This prevents backgrounding after redirection
            intent.launchUrl(context, uri);
        
        @Override
        public void onServiceDisconnected(ComponentName name) 
    ;
    CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", connection);

这不起作用:

void launchTab(Context context, Uri uri)
    final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
    final CustomTabsIntent intent = builder.build();
    intent.launchUrl(context, uri);

Chrome Custom Tab docs 将热身描述为最佳实践,但它似乎也有助于确保预期行为。

在环境方面,我正在使用 Chrome 51 的 Nexus 5X 上进行测试。我在 Gradle 中的 chrome 选项卡依赖项如下所示:

dependencies 
    compile 'com.android.support:customtabs:24.0.0'

【讨论】:

我已经有 client.warmup(0L) 并且我的应用程序仍然做同样的事情。还有其他想法吗? 我应该给什么包名而不是“com.android.chrome”。我应该给我的应用程序包名称吗? @Ajinkya,这个包名就是将被实例化的 Chrome Custom Tabs 包的名字(例如com.android.chromecom.browser.that.support.customTabs.)。所以不,不要把你的包名放在那里。【参考方案2】:

如果我使用 android:launchMode="singleInstance" 任务管理器中有多个实例,所以这是没有选择的。

使用 FLAG_ACTIVITY_NEW_TASK 标志启动 CustomTabsIntent 就可以了。

CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent intent = builder.build();

intent.intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
intent.launchUrl(context, Uri.parse(url));

【讨论】:

【参考方案3】:

它帮助我在清单文件中将用于启动 CustomTab 的 Activity 设置为 singleInstance 模式:

    <activity
        android:launchMode="singleInstance"
        android:name="com.example.SingleInstanceActivityToStartCustomTab"
    </activity>

在代码中我照常执行:

    CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
    final CustomTabsIntent customTabsIntent = builder.build();
    customTabsIntent.intent.setPackage(someChromePackage);
    customTabsIntent.launchUrl(singleInstanceModeActivity, someUriThatDoesRedirect);

我尝试预热 Chrome,甚至在调用 client.warmup(0l); 后稍有延迟地调用 customTabsIntent.launchUrl(),但都没有帮助。

【讨论】:

【参考方案4】:

我很确定这是 Chrome 中的错误造成的。我将我的所有设备(GS6、GS7、Nexus 7 和 Nexus 9)都更新到了最新版本的 Chrome,并且在发生重定向时我的应用不再最小化。

我今天(2016 年 11 月 3 日)才发现这个问题,所以我还没有任何关于特定错误或其后续解决方案的信息。这正是我注意到的。

希望有帮助!

【讨论】:

以上是关于Chrome 自定义标签重定向到 Android 应用程序将关闭该应用程序的主要内容,如果未能解决你的问题,请参考以下文章

从 Chrome 自定义选项卡重定向到 Android 应用程序时“导航被阻止”

尝试将来电重定向到android中的自定义UI [关闭]

从 Chrome 重定向到带有位置标头的 302 后被阻止的 Android 应用

Spring security自定义登录页面不重定向

使用 S3 静态网站托管重定向到无法在 chrome 中工作的 WWW

重定向到页面并发送自定义 HTTP 标头