Chrome 自定义标签重定向到 Android 应用程序将关闭该应用程序
Chrome Custom Tabs redirect to Android app will close the app
我正在尝试使用 Android Chrome 自定义选项卡实现 OAuth2 流程,但当 Chrome 自定义选项卡收到 302 时,我的应用程序始终关闭(没有崩溃)使用我的应用程序的 location/scheme。
如果我使用 ahref link 创建一个 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+'
}
感谢您的帮助...
我还观察到我的 Android 应用程序在服务器端 302 重定向到自定义方案后意外出现后台,并观察到独立 Chrome 的预期处理和客户端中手动触发的重定向.
我能够 "fix" 通过在加载重定向的 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 将热身描述为最佳实践,但它似乎也有助于确保预期的行为。
就环境而言,我正在 Nexus 5X w Chrome 51 上进行测试。我在 Gradle 中的 chrome 选项卡依赖项如下所示:
dependencies {
compile 'com.android.support:customtabs:24.0.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()
都没有帮助。
如果我使用 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));
我很确定这是 Chrome 中的错误造成的。我将我的所有设备(GS6、GS7、Nexus 7 和 Nexus 9)都更新到了最新版本 Chrome,当发生重定向时,我的应用程序不再最小化。
我今天 (11/3/2016) 才发现这个问题,所以我还没有关于特定错误或其后续解决方案的任何信息。这正是我注意到的。
希望对您有所帮助!
我正在尝试使用 Android Chrome 自定义选项卡实现 OAuth2 流程,但当 Chrome 自定义选项卡收到 302 时,我的应用程序始终关闭(没有崩溃)使用我的应用程序的 location/scheme。
如果我使用 ahref link 创建一个 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+'
}
感谢您的帮助...
我还观察到我的 Android 应用程序在服务器端 302 重定向到自定义方案后意外出现后台,并观察到独立 Chrome 的预期处理和客户端中手动触发的重定向.
我能够 "fix" 通过在加载重定向的 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 将热身描述为最佳实践,但它似乎也有助于确保预期的行为。
就环境而言,我正在 Nexus 5X w Chrome 51 上进行测试。我在 Gradle 中的 chrome 选项卡依赖项如下所示:
dependencies {
compile 'com.android.support:customtabs:24.0.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()
都没有帮助。
如果我使用 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));
我很确定这是 Chrome 中的错误造成的。我将我的所有设备(GS6、GS7、Nexus 7 和 Nexus 9)都更新到了最新版本 Chrome,当发生重定向时,我的应用程序不再最小化。
我今天 (11/3/2016) 才发现这个问题,所以我还没有关于特定错误或其后续解决方案的任何信息。这正是我注意到的。
希望对您有所帮助!