I'm using branch.io SDK in my Android app and want to make my app a default handler for branch links on Android 6 as described here(Android guide) and here(Branch.io guide)
This is my activity's declaration in AndroidManifest.xml:
<activity android:name="com.mypackage.MyActivity"
android:launchMode="singleTask">
<intent-filter tools:node="merge" android:autoVerify="true">
<data android:scheme="@string/url_scheme" android:host="open"/>
<data android:scheme="https"
android:host="@string/branch_io_host"
android:pathPrefix="@string/branch_io_path_prefix"/>
<data android:scheme="http"
android:host="@string/branch_io_host"
android:pathPrefix="@string/branch_io_path_prefix"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
However when I install a build on my device, I still keep seeing the chooser dialog when I click on a link with proper host and path. After readin through this extensive guide on app linking, I believe this is happening because my device never verifies my app's intent filter. E.g. when I install a Twitter app from the play store, I see these messages in LogCat:
03-24 15:04:27.231: D/IntentFilterVerificationReceiver(16965): Received ACTION_INTENT_FILTER_NEEDS_VERIFICATION.
03-24 15:04:27.248: I/IntentFilterIntentService(16965): Verifying IntentFilter. verificationId:2 scheme:"https" hosts:"twitter.com www.twitter.com ads.twitter.com" package:"com.twitter.android".
03-24 15:04:30.134: I/IntentFilterIntentService(16965): Verification 2 complete. Success:true. Failed hosts:.
But I don't see messages like this when I install my app. I tried both release and debug builds, tried uploading it to Alpha testing in the play store and installing from there, same result. Why does Android not verify my Intent filter?
You can review and manage app links in the system Settings app, under Settings > Apps > App Info > Open by default.
Android Studio makes it very easy to test deep links. Click Run > Edit Configurations to edit the configuration of the project. Open the General tab at the top and enter the URI in the Deep Link field in the Launch Options section.
Fixed this by moving this data tag into a separate intent filter:
<data android:scheme="@string/url_scheme" android:host="open"/>
This is what AndroidManifest looks like now:
<activity android:name="com.mypackage.MyActivity"
android:launchMode="singleTask">
<intent-filter tools:node="merge" android:autoVerify="true">
<data android:scheme="https"
android:host="@string/branch_io_host"
android:pathPrefix="@string/branch_io_path_prefix"/>
<data android:scheme="http"
android:host="@string/branch_io_host"
android:pathPrefix="@string/branch_io_path_prefix"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
<intent-filter>
<data android:scheme="@string/url_scheme" android:host="open"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
Messages from IntentFilter now show up in the log as intended.
For Deeplink to work without user prompt
Suppose your app manifest declares multiple hosts like myhost1.com, myhost2.com & myhost3.com,
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="myhost1.com"
android:pathPrefix="/start" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="myhost2.com"
android:pathPrefix="/start" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="myhost3.com"
android:pathPrefix="/start" />
</intent-filter>
and deploys assetlinks.json for each one
https://myhost1.com/.well-known/assetlinks.json
https://myhost2.com/.well-known/assetlinks.json
https://myhost3.com/.well-known/assetlinks.json
While Installing the app from ADB or Google Play store keep checking your Logcat for IntentFilterIntentOp tag as follows
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:9 scheme:"https" hosts:"myhost1.com myhost2.com myhost3.com" package:"com.mydeeplink.app". [CONTEXT service_id=244 ]
On installation, the manifest declaration is verified if ANYONE host fails your DIRECT opening of the deep link will not work. Failure means the user will be prompted to choose either your app or browser.
NOTE NOTE NOTE: If you declare any test environment in the manifest which will be removed in the future. It will cause IntentFilterIntentOp FAILURE for your apps. It will break the direct opening of the deep link.
For the test environments, which will be removed later do not use android:autoVerify="true". Otherwise your production app deep link direct opening might be broken for the new installations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With