Types of links Link to heading
- Deep Links
- URIs of any scheme that take users directly to a specific part of your app
- eg. portfolio://deeplink/home, https://randx829.github.io/portfolio/deeplink/home
- Web Links
- Deep links that use the HTTP and HTTPS schemes
- eg. https://randx829.github.io/portfolio/deeplink/home
- Android App Links
- Web links that use the HTTP and HTTPS schemes and contain the autoVerify attribute
- Available on Android 6.0 (API level 23) and higher
How it works Link to heading
When a Intent is invoked(manually or programmatically)
The Android System tries following actions in sequential order
- Open the user’s preferred app(if designated)
- Open the only available app
- Show chooser dialog or open in default browser
Implementation Link to heading
Add intent filters for incoming links Link to heading
💡Android routes any Intent that has matching URIs to your app at runtime
💡multiple data elements in the same intent filter are actually merged together to account for all variations of their combined attributes
💡Atrribute is case-sensitive, using lowercase letters
💡If multiple activities contain intent filters that resolve to the same verified Android App Link, then there’s no guarantee as to which activity handles the link.
- action
- VIEW
- data
- scheme
- eg. portfolio, https
- host
- eg. deeplink, randx829.github.io
- port(optional)
- eg. 80, 443
- path
- must begin with a /
- eg. portfolio/deeplink/home
- pathPrefix
- must begin with a /
- eg. /portfolio
- pathSuffix
- Starting in Android 12 (API level 31)
- doesn’t have to begin with the /
- eg. home
- pathPattern
- eg. .*
- pathAdvancedPattern
- Starting in Android 12 (API level 31)
- eg. [a-zA-Z]
- scheme
- category
- BROWSABLE
- to receive intents from a web browser
- DEFAULT
- to receive implicit intents
- BROWSABLE
Verify Android App Links Link to heading
💡The Digital Asset Links protocol treats subdomains in your intent filters as unique, separate hosts
💡Command to generate SHA256 fingerprint: keytool -list -v -keystore my-key.keystore
- Add intent filters that contain the autoVerify attribute
- Supporting app linking for multiple hosts
- Supporting app linking for multiple subdomains
- Check for multiple apps associated with the same domain
- Declare the association by hosting a Digital Asset Links JSON file
- Associating a website with multiple apps
- Associating multiple websites with a single app
- Publishing the JSON verification file
- location: https://yourdomain/.well-known/assetlinks.json
- content-type application/json
- accessible over an HTTPS connection
- accessible without any redirects (no 301 or 302 redirects)
- If support multiple host domains, must publish the assetlinks.json file on each domain
- accessible to the public (not behind a VPN)
- Verify your app
- Auto verification
- The Android system inspects all intent filters and queries the corresponding websites for the Digital Asset Links file
- Manual verification
- Support the updated domain verification process
- adb shell am compat enable 175408749 PACKAGE_NAME
- eg. adb shell am compat enable 175408749 tokyo.randx.portfolio.android.deeplink
- Reset the state of Android App Links on a device
- adb shell pm set-app-links –package PACKAGE_NAME 0 all
- eg. adb shell pm set-app-links –package tokyo.randx.portfolio.android.deeplink 0 all
- Invoke the domain verification process
- adb shell pm verify-app-links –re-verify PACKAGE_NAME
- eg. adb shell pm verify-app-links –re-verify tokyo.randx.portfolio.android.deeplink
- Review the verification results
- adb shell pm get-app-links PACKAGE_NAME
- eg. adb shell pm get-app-links tokyo.randx.portfolio.android.deeplink
- Support the updated domain verification process
- Auto verification
AndroidManifest Snippet👇
<activity
android:name=".DeeplinkActivity"
android:exported="true">
<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="randx829.github.io"
android:pathPrefix="/portfolio"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="portfolio"
android:host="deeplink" />
</intent-filter>
</activity>
Read data from incoming intents Link to heading
Call the getData() and getAction() methods to retrieve the data and action associated with the incoming Intent.
💡generally do so during onCreate() or onStart()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
val action: String? = intent?.action
val data: Uri? = intent?.data
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val action: String? = intent?.action
val data: Uri? = intent?.data
}
Test your deep links Link to heading
- Launch app
- adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d “http://domain.name:optional_port”
- eg. adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d “https://randx829.github.io/portfolio/deeplink/home"
Tools Link to heading
Best practices Link to heading
- Create separate intent-filter when your intention is to declare unique URLs
- Add autoVerify to each intent-filter element for consistency
Behavior changes Link to heading
- Starting in Android 12 (API level 31), unresolved web links will be opened in default browser
- Starting in Android 12 (API level 31), you can manually verify how the system resolves your Android App Links.
- On Android 11 (API level 30) and lower, the system doesn’t verify your app as a default handler unless it finds a matching Digital Asset Links file for all hosts that you define in the manifest.