Search code examples
androidandroid-manifestandroid-instant-appsandroid-app-bundleandroid-app-links

Instant app with Dynamic Features always show Disambiguation dialog with 1 option


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.


Solution

  • There is a possible solution for using URI intents with dynamic features instead of switching to reflection. You can use a trick where you can get the needed class name during run time with packageManager.queryIntentActivities(), so you don't have to use the hardcoded Activity name.

    The following extension function is an example of how you could convert your Intent using the URI or deep link into one that will not show the chooser dialog:

    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)
    }
    

    Then you can simply do:

    intent.convertToSafeDynamicFeatureModuleIntent(context)
    startActivity(intent)
    

    A longer explanation can be found here