3

I am trying to open an Activity using Android App Links. Activity is in a dynamic feature module, in the Google's Sample project.

I haven't uploaded the project to the Google Play, so I am testing using the debug build type, with a run configuration that includes the all dynamic features to the APK.

The code I want to test is:

 private fun openUrl(url: String) { // url will be "http://uabsample-405d6.firebaseapp.com/url"
    var intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
    intent.setPackage(packageName)
    intent.addCategory(Intent.CATEGORY_BROWSABLE)
    startActivity(intent)
}

But when I try to navigate to the URL Feature, Android shows the application chooser dialog showing the same app twice:

result

Do you know why this is happening? Is this an intended behaviour?

Android Manifest of Url Module:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.android.samples.instantdynamicfeatures">

    <dist:module
        dist:instant="true"
        dist:onDemand="false"
        dist:title="@string/title_url_instant_module">
        <dist:fusing dist:include="true" />
    </dist:module>

    <application>
        <activity
            android:name="com.android.samples.instantdynamicfeatures.UrlInstantModuleActivity"
            android:label="@string/title_activity_url_instant_module"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter
                android:autoVerify="true"
                android:order="1">
                <action android:name="android.intent.action.VIEW" />

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

                <data
                    android:host="uabsample-405d6.firebaseapp.com"
                    android:path="/url"
                    android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Strings

<resources>
    ...
    <string name="title_url_instant_module">url</string>
    <string name="title_activity_url_instant_module">url_instant_module_activity</string>
</resources>

Update: I forgot to mention: I changed the sample project's application id with mine and placed the well-known Json on my website. I checked using App Links Assistant and it was fine.

Mustafa Berkay Mutlu
  • 1,929
  • 1
  • 25
  • 37

2 Answers2

0

This seems to be an bug in dynamic feature on using URI intent which has been reported here.For the google sample repo the bug is reported here The only possible solution I can give at this point is, For time being we can use reflection to make this work.

  private fun openUrl(url: String) {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
        intent.setPackage(BuildConfig.APPLICATION_ID)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.setClassName(getPackageName(),"com.android.samples.instantdynamicfeatures.UrlInstantModuleActivity")
        intent.addCategory(Intent.CATEGORY_BROWSABLE)
        startActivity(intent)
    }

Use the application package name and activity class name in setClassName function. However this is not the official recommended method.For more information check this.

0

There is a possible solution for using URI intents with dynamic features. 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