Перенаправление Chrome Custom Tabs в приложение Android закроет приложение
Я пытаюсь реализовать поток OAuth2 с помощью пользовательской вкладки Android Chrome, но мое приложение всегда закрыто (без сбоев), когда пользовательская вкладка Chrome получает 302 с расположением / схемой моего приложения.
Если я создаю HTML-страницу со ссылкой ahref и вручную нажимаю на нее, то настраиваемая вкладка Chrome корректно переключается на мое приложение.
Похоже, что при обработке перенаправления сервера 302 в пользовательской вкладке Chrome он не будет корректно обрабатывать мою пользовательскую схему приложения... но почему?
Если я попробую тот же URL перенаправления в стоковом браузере или с WebView, все тоже работает.
Вот моя текущая настройка:
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>
Это URL-адрес перенаправления, полученный приложением с кодом HTTP 302:
myappscheme: // OAuth код =1234567& состояние = 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+'
}
Спасибо за любую помощь...
4 ответа
Я также наблюдал неожиданный фон моего Android-приложения после перенаправления на серверную сторону 302 в пользовательскую схему и наблюдал ожидаемую обработку от автономного Chrome и ручное перенаправление, инициируемое клиентом.
Я смог "исправить" проблему, вызвав функцию разминки перед загрузкой URL, который перенаправляет.
Другими словами, это работает:
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 описывают прогревание как лучшую практику, но оно также помогает обеспечить ожидаемое поведение.
С точки зрения env, я тестирую Nexus 5X с Chrome 51. Моя зависимость от Chrome Tab в Gradle выглядит следующим образом:
dependencies {
compile 'com.android.support:customtabs:24.0.0'
Если я использовал android:launchMode="singleInstance", в диспетчере задач было несколько экземпляров, так что это было невозможно.
Запуск CustomTabsIntent с флагом FLAG_ACTIVITY_NEW_TASK сделал свое дело.
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent intent = builder.build();
intent.intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
intent.launchUrl(context, Uri.parse(url));
Это помогло мне установить Activity, которую я использую для запуска CustomTab, в режим 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 и даже звонить customTabsIntent.launchUrl()
с некоторой задержкой после звонка client.warmup(0l);
и ни один не помог.
Я почти уверен, что это результат ошибки в Chrome. Я обновил все свои устройства (GS6, GS7, Nexus 7 и Nexus 9) до последней версии Chrome, и мое приложение больше не сворачивается, когда происходит перенаправление.
Я только что обнаружил это сегодня (3.11.2016), поэтому у меня пока нет никакой информации о конкретной ошибке или ее последующем устранении. Это только то, что я заметил.
Надеюсь, это поможет!