Мгновенное приложение с динамическими функциями всегда показывает диалог устранения неоднозначности с 1 опцией

Я экспериментирую с динамическими функциями и мгновенными приложениями. Для навигации по различным функциям я использую Deep Links.

Каждый раз, когда я перехожу к другому действию, я вижу диалоговое окно устранения неоднозначности в течение менее 1 секунды, с одним приложением в списке. Обратите внимание, что параметры "Once" и "Always" (на голландском языке) выделены серым цветом.

Пример проекта Github

Я создал минималистичный образец, который соответствует моей текущей структуре на Github. Требуется Android Studio 3.5 - RC2

Некоторый контекст:

Я вполне уверен, что ссылки настроены правильно. Но так как вы, ребята, хотите это проверить в любом случае, вот конфигурация:

1 - Манифест:

<activity
            android:name=".ProfileActivity">

        <intent-filter
                android:autoVerify="true"
                android:priority="100">

            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data
                    android:host="giddy.entreco.nl"
                    android:pathPrefix="/profile"
                    android:scheme="http" />
            <data android:scheme="https" />

        </intent-filter>

    </activity>

2 - Assetlinks Мой домен содержит общедоступный assetlinks.json

3 - Ша верны Ша, которые я использую, верны

Executing tasks: [signingReport] in project

SHA1: 3A:52:19:77:C1:AD:18:F4:98:21:77:74:37:DC:9B:89:02:64:6E:C6
SHA-256: 25:DD:C3:7B:8E:35:D3:39:D5:D4:6C:B5:EA:7D:14:AF:82:EC:9C:56:A6:F5:76:A3:E1:D7:69:B3:EC:58:72:E8
Valid until: Saturday, March 21, 2048

4 - файл с подтвержденными ссылками на цифровые активы. Все проверки проходят.

5 - Тестирование намерения URL также работает! Единственная проблема в том, что я вижу диалог устранения неоднозначности в течение короткого периода времени.

Дополнительная информация

  • я использую apply plugin: 'com.android.dynamic-feature' во всех моих модулях (кроме app конечно)

  • Android Studio: 3.5 RC2; Android-gradle-плагин: 3.5.0-rc02

  • Мое устройство - OnePlus6 - с Oxygen 9.0.7 и Android 9

  • Официальный пример Google также показывает это поведение на моем устройстве

  • Некоторые устройства Samsung ведут себя по-разному. Вместо отображения параметра "Устранение неоднозначности с 1" он дважды отображает мое приложение и будет ждать, пока вы не выберете Once или "Всегда". (Обратите внимание, я получил это из отчетов перед запуском в магазине Play)

  • Я вижу это поведение, независимо от того, собираю ли я APK, пакет приложений или загружаю через Google Play. Это всегда то же самое.

Любые предложения, чтобы убрать этот раздражающий диалог? Когда я анализирую apk/bundle, я вижу две записи для конкретного Activity, Однажды в base module's manifest но и в profile module's manifest, У меня мало понимания того, как Android/PlayStore объединяет эти манифесты при установке модулей, но я думаю, что в этом случае имеет смысл увидеть диалог.

2 ответа

Решение

Так что да... Я полагаю, что я видел это раньше, это странное поведение при переходе от одного динамического объекта (мгновенного) к другому (не мгновенного) через намерение URL.

До тех пор, пока это не будет решено, я не рекомендую использовать намерение URL для перехода между модулями, вместо этого используйте отражение, чтобы напрямую перейти к активности другого модуля, например:

if (doesModuleExist()) {
    val intent = Intent()
        .setClassName(getPackageName(), "com.sample.ProfileActivity")
        .addCategory(Intent.CATEGORY_DEFAULT)
        .addCategory(Intent.CATEGORY_BROWSABLE)
    startActivity(intent)
}

где doesModuleExist() проверяет:

  1. Изучив ваш пример манифеста, похоже, ваш модуль профиля не является частью вашего мгновенного приложения dist:instant="false", так что у вас никогда не будет доступа к нему, поэтому вы можете просто сделать isNotInstantApp() проверьте вместо этого и никогда не пытайтесь запустить приложение в качестве мгновенного приложения.

  2. после того, как вы установили приложение, вам технически не нужно проверять, как это всегда бывает include="true"

  3. но если ваш модуль профиля является модулем onDemand или просто из соображений безопасности, вы должны использовать splitInstallManager.getInstalledModules()см. / app-bundle / playcore # manage_installed_modules (обратите внимание, вы также можете использовать этот API в вашем приложении)

И так как это странное поведение различается для разных устройств, это может означать, что они реализовали тонкие различия в перехвате и обработке этого URL-намерения, и / или это просто другая версия Android (pre-O против O+).

Также да, связывание нескольких имен пакетов в одном домене веб-сайта для common.handle_all_urls может привести к некоторому дополнительному неправильному поведению, когда система пытается проверить связь при запуске приложения.

Существует возможное решение для использования намерений URI с динамическими функциями вместо переключения на отражение. Вы можете использовать трюк, где вы можете получить необходимое имя класса во время выполнения с помощью packageManager.queryIntentActivities(), поэтому вам не нужно использовать жестко заданное имя действия.

Следующая функция расширения является примером того, как вы можете преобразовать свой Intent, используя URI или глубокую ссылку, в тот, который не будет отображать диалоговое окно выбора:

      fun Intent.convertToSafeDynamicFeatureModuleIntent(context: Context) {
    //Get list of all intent handlers for this Intent. This should only be the actual activity we are looking for
    val options = context.packageManager.queryIntentActivities(this, PackageManager.MATCH_DEFAULT_ONLY)
    //Set the activity that supported the given intent
    setClassName(packageName, options[0].activityInfo.name)
}

Тогда вы можете просто сделать:

      intent.convertToSafeDynamicFeatureModuleIntent(context)
startActivity(intent)

Более подробное объяснение можно найти здесь