Chrome自定义选项卡重定向到Android应用程序将关闭该应用程序。

19

我正试图使用Android Chrome自定义选项卡实现OAuth2流程,但当Chrome自定义选项卡接收到我的应用程序方案的302时,我的应用程序始终关闭(没有崩溃)。

如果我创建一个包含href链接并手动触摸它的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+'
}

感谢任何帮助...


1
从我的理解来看,您的应用程序被恢复然后关闭了,是这样吗?logcat 上是否有任何相关消息?此外,您能否发布 MainActivity.java 代码? - andreban
仅供记录,我刚刚使用Webview测试了将重定向(302)到自定义方案(myappscheme://...),但它无法工作。它显示“未知方案”。 - User
4个回答

12
我也观察到我的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文档中提到预热是最佳实践,但它似乎也有助于确保预期的行为。

就环境而言,我正在使用Nexus 5X和Chrome 51进行测试。我的Gradle中的Chrome Tab依赖项如下:

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

2
我已经运行了client.warmup(0L)但我的应用程序仍然有相同的问题。还有其他建议吗? - scoleman2272
1
我应该给什么包名而不是“com.android.chrome”?我应该给我的应用程序包名吗? - Ajinkya
@Ajinkya,那个包名是Chrome自定义选项卡包的名称,将被实例化(例如com.android.chromecom.browser.that.support.customTabs)。因此,请不要在那里放置您的包名。 - Sakiboy
那很有趣,它是如何工作的? - walkmn

9
如果使用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));

不起作用。 - walkmn

0

它帮助我在清单文件中将我用来启动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(),但都没有帮助。


0

我相信这是Chrome中的一个bug导致的结果。我将我的所有设备(GS6,GS7,Nexus 7和Nexus 9)更新到了最新版本的Chrome,当重定向发生时,我的应用程序不再被最小化。

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

希望这有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接