5

I'm experimenting with Dynamic Features and Instant Apps. To navigate between various features, I use Deep Links.

Each time I navigate to another Activity, I see the disambiguation dialog for less than 1 second, with 1 app listed. Notice how the options for "Once" and "Always" (in dutch) are greyed out.

Sample Github Project

I created a minimalistic sample, that matches my current structure on Github. Requires Android Studio 3.5 - RC2

Disambiguation dialog shown briefly

Some Context:

I'm quite confident, the deeplinks are configured correct. But since you guys want to check that anyway, here's the configuration:

1 - Manifest:

<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 My domain contains a publicly accessible assetlinks.json

3 - Sha's are correct The sha's I use are correct

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 - Confirmed digital asset link file All checks pass https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://giddy.entreco.nl&relation=delegate_permission/common.handle_all_urls

5 - Testing a URL intent Also works! The only problem is I see the disambiguation dialog for a brief period.

Additional info

  • I use apply plugin: 'com.android.dynamic-feature' in all my modules (except app off course)

  • Android Studio: 3.5 RC2; Android-gradle-plugin: 3.5.0-rc02

  • My Device is a OnePlus6 - with Oxygen 9.0.7 & Android 9

  • The google official sample also shows this behaviour on my device

  • Some Samsung devices, behave different. Instead of showing the Disambiguation with 1 option, it lists my app twice, and will keep waiting until you either select Once or 'Always'. (Note, I got this from the pre-launch reports in the play store) enter image description here

  • I see this behaviour, no matter if I build an APK, an App Bundle or download through Google Play. It's always the same.

Any suggestions to get that annoying dialog out of the way? When I analyse the apk/bundle, I do see two entries for the specific Activity. Once in the base module's manifest, but also in the profile module's manifest. I have little understanding of how Android/PlayStore merges those manifests while installing modules, but I guess it could make sense to see the dialog in this case.

4

2 回答 2

4

所以是的......我相信我以前见过这个,当通过 URL 意图从一个动态功能(即时)导航到另一个(非即时)时,这是一些奇怪的行为。

在解决此问题之前,我不建议使用 URL 意图在模块之​​间导航,而是使用反射直接访问其他模块的活动,例如:

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

WheredoesModuleExist()检查是否:

  1. 检查您的示例清单,看起来您的配置文件模块不是您的即时应用程序的一部分dist:instant="false",因此您将永远无法访问它,因此您可以简单地进行isNotInstantApp()检查,并且永远不要在作为即时应用程序时尝试启动。

  2. 一旦在您安装的应用程序中,那么您在技术上不需要检查,因为它总是include="true"

  3. 但是如果您的配置文件模块是按需模块,或者只是为了安全预防措施,您应该使用splitInstallManager.getInstalledModules(),请参阅/app-bundle/playcore#manage_installed_modules (注意,您也可以在您的即时应用程序中使用此 API)

由于看起来这种奇怪的行为在不同的设备之间有所不同,这可能意味着它们在拦截和处理该 URL 意图方面实现了细微的差异,和/或它只是一个不同的 Android 版本(pre-O 与 O+)。

common.handle_all_urls同样是的,当您的应用程序上线时系统尝试验证关联时,将多个包名称关联到单个网站域可能会导致一些额外的不当行为。

于 2019-08-05T23:21:55.040 回答
1

有一种可能的解决方案是使用具有动态特性的 URI 意图而不是切换到反射。您可以使用一个技巧,在运行时通过 packageManager.queryIntentActivities() 获取所需的类名,因此您不必使用硬编码的 Activity 名称。

以下扩展函数是一个示例,说明如何使用 URI 或深层链接将 Intent 转换为不会显示选择器对话框的 Intent:

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)

可以在这里找到更长的解释

于 2021-01-03T20:09:14.113 回答