How it works Link to heading

When a Intent is invoked(manually or programmatically)
The Android System tries following actions in sequential order

  1. Open the user’s preferred app(if designated)
  2. Open the only available app
  3. Show chooser dialog or open in default browser

Implementation 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]
  • category
    • BROWSABLE
      • to receive intents from a web browser
    • DEFAULT
      • to receive implicit intents

💡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

  1. 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
  2. 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)
  3. 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

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
}

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.

Reference Link to heading