Short answer: Android App Links need an intent filter with android:autoVerify="true" for your http and https hosts, and an assetlinks.json file at https://<host>/.well-known/assetlinks.json naming your package and the SHA-256 fingerprint of the key that signs the installed app. Verify with adb shell pm get-app-links and look for verified.
What is an Android App Link?
Android App Link: an http or https URL on a domain you have verified with Digital Asset Links, which Android opens directly in your app without asking the user to choose.
A plain deep link (a custom scheme, or an unverified web URL) can be claimed by other apps and may show a chooser. Google says custom schemes have no web fallback and can be claimed by other apps. Verified App Links avoid both problems.
Step 1: add the intent filter
In AndroidManifest.xml, add a filter to the activity that handles links:
<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>
autoVerify: Google says it "is required for App Links".BROWSABLE: "Without it, clicking a link in a browser cannot resolve to your app."- Schemes: include
httpandhttps. Google's sample notes: "Do not include other schemes, as this will prevent verification." - Merging: multiple
<data>elements in one filter are merged into every combination, so use separate filters for distinct scheme and host pairs.
Step 2: get the right fingerprint
The fingerprint must match the certificate that signs the app users install.
- Without Play App Signing: run
keytool -list -v -keystore my-release-key.keystoreand copy the SHA-256 value. - With Play App Signing: open Play Console > Protected with Play > Play Store distribution > Play app signing, and copy the app signing key's SHA-256. Google says a local keytool fingerprint "will usually not match the one on users' devices".
A valid value is 32 uppercase hex pairs joined by colons, 95 characters long. You can list several fingerprints, for example debug and release.
Step 3: write and host assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
Host rules from Google:
- At
https://<host>/.well-known/assetlinks.json, over HTTPS. - Served as
application/json. - No 301 or 302 redirects; anything other than a 200 gives an empty statement list.
- On every host in the manifest. For
*.example.com, publish at the root hostname.
Check the published file with curl -I https://example.com/.well-known/assetlinks.json and Google's Statement List tester.
Why do App Links open the browser on Android 12?
From Android 12, Google says a web intent only opens your app if the app is approved for that specific domain; otherwise it resolves to the default browser.
How hosts are judged also changed:
- Android 11 and lower: all hosts in the manifest must verify, or none do. One staging or VPN-only host breaks everything. See one host fails.
- Android 12 and later: each host is verified separately.
- Apps targeting lower SDKs can opt into the new verification for testing with
adb shell am compat enable 175408749 PACKAGE_NAME.
Step 4: verify on a device
Install 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
adb shell pm get-app-links com.example.app
The device must be online. Wait a few minutes before reading the result. Only verified means success. Other states include none, approved, denied, legacy_failure and codes of 1024 and above for verifier errors.
Then fire a test link:
adb shell am start -W -a android.intent.action.VIEW -d "https://example.com/product/1" com.example.app
Step 5: check with Google's tools
- Digital Asset Links API:
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urlsshows what Google reads. - Google's Statement List tester: tests a published statement file.
- Play Console > Grow > Deep links: lists deep links and configuration errors.
- Android Studio App Links Assistant: validates the setup from Tools > App Links Assistant.
When you change the file later, remember the timing. On Android 14 and lower, updates are usually picked up on install or update. On Android 15 and later, changes can take up to seven days. Re-run adb shell pm get-app-links before each release.