Short answer: Android only verifies App Links for intent filters with android:autoVerify="true". The filter also needs the VIEW action, DEFAULT and BROWSABLE categories, and <data> for http and https with your host. On Android 12 and later, an unverified app does not get web links at all; they go to the browser.
What is happening
autoVerify: the android:autoVerify="true" attribute on an intent filter that tells Android to check assetlinks.json for the filter's hosts at install time.
Google says "The android:autoVerify="true" attribute is required for App Links." Verification runs on install on Android 6.0 and later when at least one filter has it. Without it, your file is never checked.
Android 12 made this stricter. Google's behaviour change notes say a generic web intent "resolves to an activity in your app only if your app is approved for the specific domain", otherwise it "resolves to the user's default browser app instead".
Why does this happen?
Filters copied from custom scheme deep link examples often lack the attribute, the category or the https data. Each piece matters:
- No autoVerify: Android never tries to verify the hosts.
- No BROWSABLE: Google says "Without it, clicking a link in a browser cannot resolve to your app."
- Missing scheme: the filter needs both
httpandhttps. Google's sample manifest warns: "Do not include other schemes, as this will prevent verification." - Merged data elements: Google notes that multiple
<data>elements in one filter are merged into every combination, so mixing hosts or schemes in one filter can claim more than you meant.
How to confirm it
- Open
AndroidManifest.xmland find the filter for your web links. - Check for
android:autoVerify="true",android.intent.action.VIEW,DEFAULTandBROWSABLE. - On a device, run
adb shell pm get-app-links com.example.app. A domain missing from the output, or with a state other thanverified, points to the filter or the file. - Use Android Studio's App Links Assistant (Tools > App Links Assistant) to validate the configuration.
How to fix it
- Add
android:autoVerify="true"to the filter. - Include the
VIEWaction and bothDEFAULTandBROWSABLEcategories. - Add
<data>forhttpandhttpswith your host. Keep custom schemes in a separate filter. - Use separate filters for distinct scheme and host combinations.
- Reinstall the app, wait at least 20 seconds, then run
adb shell pm set-app-links --package com.example.app 0 all,adb shell pm verify-app-links --re-verify com.example.app, andadb shell pm get-app-links com.example.app.
<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="http" />
<data android:scheme="https" />
<data android:host="example.com" />
</intent-filter>
Make sure the file side is right with curl -I https://example.com/.well-known/assetlinks.json and Google's Statement List tester. The Android App Links setup guide walks through both halves, and one host fails covers apps with several domains.