Почему сборщик аккаунтов в приложении Android отменяется?

Следуя документации "Пять минут быстрого запуска" для загрузки файла с устройства Android на Google Drive, я написал тестовое приложение, которое успешно загружает файл, но моя попытка скопировать соответствующий код в более крупное приложение не загружает файл. файл, потому что его средство выбора учетной записи Google всегда отменяется:

  • код результата onActivityResult() равен 0 (т. е. RESULT_CANCELED),
  • аргумент намерения onActivityResult() равен нулю, и
  • logcat (показанный ниже) показывает, что "Активность запускается как новая задача, поэтому отмена результата активности".

04-22 02:04:25.098: D/alsa_ucm(162): snd_use_case_set(): uc_mgr 0x40e59388 идентификатор _verb значение HiFi Lowlatency
04-22 02: 04: 25.098: D / alsa_ucm (162): настройка управления микшером для включения динамика 1
04-22 02: 04: 25.098: D / ACDB-LOADER (162): ACDB -> send_afe_cal
04-22 02: 04: 25.098: I / ActivityManager (526): НАЧАТЬ u0 {act=com.google.android.gms.common.account.CHOOSE_ACCOUNT cmp=com.google.android.gms/.common.account.AccountPickerActivity (есть дополнения)} из pid 3484
04-22 02: 04: 25.098: W / ActivityManager (526): действие запускается как новая задача, поэтому отменяется результат действия.
04-22 02: 04: 25.108: D / alsa_ucm (162): настройка управления микшером для HiFi Lowlatency enable 1
04-22 02: 04: 25.108: D / ALSAModule (162): возвращаемое значение устройства: hw: 0,14
04-22 02: 04: 25.118: D / ALSAModule (162): setHardwareParams: reqBuffSize 1024 канала, 2 sampleRate 48000
04-22 02: 04: 25.118: D / ALSAModule (162): setHardwareParams: buffer_size 2048, period_size 1024, period_cnt 2
04-22 02: 04: 25.188: D / dalvikvm (526): GC_FOR_ALLOC освобожден 565K, 15% свободен 18562K/21684K, приостановлен 71мс, всего 71мс
04-22 02:04:25.248: D/ оверлей (159): Unset pipe =VG0 dpy=0; Unset pipe = VG1 dpy = 0; Unset pipe = RGB1 dpy = 0
04-22 02: 04: 25.248: W / InputMethodManagerService (526): окно уже сфокусировано, игнорируя усиление фокуса: com.android.internal.view.IInputMethodClient$Stub$Proxy@41ebd7e0 attribute = null, token = android.os. BinderProxy @ 42018140
04-22 02: 04: 27.991: D / dalvikvm (526): GC_FOR_ALLOC освобожден 422K, 15% свободен 18564K/21684K, приостановлено 65 мс, всего 66 мс
04-22 02:04:28.011: I/ActivityManager(526): больше не нужен com.google.android.marvin.talkback (pid 5301): пусто # 17
04-22 02: 04: 28.241: D / оверлей (159): установить канал =RGB1 dpy=0; Установить трубу =VG0 dpy=0; Установить трубу = VG1 dpy = 0;
04-22 02: 04: 28.672: D / оверлей (159): Unset pipe=VG0 dpy=0; Unset pipe=VG1 dpy=0; Unset pipe=RGB1 dpy=0;

Код, запускающий средство выбора учетной записи Google, в обоих приложениях одинаков, но средство выбора отменяется только в более крупном приложении.

// Handle item selection
case R.id.action_select_account:
    mCredential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
    Intent intent2 = mCredential.newChooseAccountIntent();
    showToast("intent extra: " + intent2.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)); // TODO: remove after test
    startActivityForResult(intent2, REQUEST_ACCOUNT_PICKER);
    return true;
default:
    return false;

Тестовое приложение и более крупное приложение являются отладочными версиями, включая одни и те же jar-файлы (показанные ниже), и работают на одном устройстве (Nexus 4, OS 4.2.2), но, как предлагается в пятиминутном кратком обзоре, каждое приложение имеет свои собственный идентификатор клиента, сгенерированный консолью API Google.

Результатом этой отмены является то, что onActivityResult() запускается сразу после того, как выбирается аккаунт Google, задолго до выбора аккаунта.

ОБНОВИТЬ:
После примерно одинакового количества проб и ошибок оказывается, что удаление следующего из AndroidManifest.xml решило проблему.

android:launchMode="singleInstance"

Мой первоначальный вопрос о том, почему сейчас переходит к тому, почему средство выбора аккаунта Google в Android должно создавать несколько экземпляров?

Спасибо,
Greg

3 ответа

Решение

Как описано в обновлении вопроса, средство выбора учетной записи начало работать, когда я удалил singleInstance launchMode из AndroidManifest.xml. Я не знаю, является ли это поведение режима запуска одного экземпляра ошибкой или отсутствием документации, но я отправил его в Android Issue Tracker: выпуск 54656

Если вы используете singleInstance, вы не разрешаете другим действиям участвовать в его задаче. Используйте вместо SingleTask.

Как указано на http://developer.android.com/guide/topics/manifest/activity-element.html несколькими пунктами вниз.

Режимы "SingleTask" и "SingleInstance" также отличаются друг от друга только в одном отношении: действие "SingleTask" позволяет другим действиям быть частью его задачи. Это всегда в корне своей задачи, но другие действия (обязательно "стандартные" и "одиночные" действия) могут быть запущены в эту задачу. С другой стороны, действие "singleInstance" не позволяет другим действиям быть частью его задачи. Это единственное занятие в задании. Если он запускает другое действие, то это действие назначается другой задаче, как если бы FLAG_ACTIVITY_NEW_TASK был в намерении.

По какой-то причине у намерения, возвращаемого менеджером учетных записей, установлено значение singleTop, что всегда приводит к немедленному сбою onActivityResult и возвращению 0 resultCode (Activity.RESULT_CANCELLED) или чего-либо еще. Мне пришлось обнулить флаги намерения, чтобы предотвратить это

// prevent running AccountPicker as SingleTop which fails and calls onActivityResult immediately otherwise
intent.setFlags(0);
startActivityForResult(intent, AccountManagerUtils.GOOGLE_AUTH_REQUEST_CODE);
Другие вопросы по тегам