Supported on: Android SDK 1.0.33+
The deep links module handles deferred deep links — routing users to the correct screen on first launch after installing from a link. This enables attribution tracking, referral programs, and contextual first-launch experiences.
Deferred Deep Links
A deferred deep link works across the install boundary:
- User clicks a link on the web (e.g.,
https://yourapp.com/workout/123?ref=instagram)
- User is redirected to the Play Store and installs your app
- On first launch, the SDK resolves the original link and returns the destination
AppDNA.checkDeferredDeepLink { deepLink ->
if (deepLink != null) {
// deepLink.screen = "/workout/123"
// deepLink.params = mapOf("ref" to "instagram")
navigate(deepLink.screen, deepLink.params)
}
}
checkDeferredDeepLink is a static method on AppDNA. It should be called once on first launch, typically after configure() completes. The SDK uses the Google Install Referrer API plus AppDNA’s visitor-context resolution. It returns null if no deferred link is found or if the app was not installed from a link.
Deferred Deep Link Check
checkDeferredDeepLink is a top-level method on AppDNA, not part of the deep links module:
AppDNA.checkDeferredDeepLink { deepLink ->
if (deepLink != null) {
navigate(deepLink.screen, deepLink.params)
}
}
Module Access
val deepLinks = AppDNA.deepLinks
Module Methods
| Method | Signature | Description |
|---|
setDelegate | setDelegate(delegate: AppDNADeepLinkDelegate?) | Set a delegate for deep link callbacks |
handleURL | handleURL(url: String) | Pass an incoming deep link URL to the SDK for processing |
DeferredDeepLink
| Property | Type | Description |
|---|
screen | String | Target screen path (e.g., "/workout/123") |
params | Map<String, String> | Additional parameters (e.g., referrer, campaign) |
visitorId | String | The visitor identifier from the originating link |
AppDNADeepLinkDelegate
Register a delegate for deep link events:
interface AppDNADeepLinkDelegate {
fun onDeepLinkReceived(url: String, params: Map<String, String>)
}
Example Implementation
import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.AppDNADeepLinkDelegate
import android.net.Uri
class LinkHandler : AppDNADeepLinkDelegate {
override fun onDeepLinkReceived(url: String, params: Map<String, String>) {
// Route based on the incoming URL
val path = Uri.parse(url).path ?: "/"
route(path, params)
}
private fun route(screen: String, params: Map<String, String>) {
when {
screen.startsWith("/workout/") -> {
val id = screen.removePrefix("/workout/")
showWorkout(id)
}
screen == "/referral" -> showReferralWelcome(params["ref"])
else -> showHome()
}
}
private fun showWorkout(id: String) { /* ... */ }
private fun showReferralWelcome(referrer: String?) { /* ... */ }
private fun showHome() { /* ... */ }
}
AppDNA.deepLinks.setDelegate(LinkHandler())
App Links
To support App Links on Android:
- Add intent filters to your
AndroidManifest.xml:
<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="yourapp.com" />
</intent-filter>
- Host a Digital Asset Links file at
https://yourapp.com/.well-known/assetlinks.json.
Handling in Activity
Pass the incoming intent’s data URL to the SDK:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent?.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}
Auto-Tracked Events
| Event | Trigger |
|---|
deep_link_handled | A deep link URL is processed |
deferred_deep_link_resolved | A deferred deep link is resolved on first launch |
Full Example
import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.AppDNADeepLinkDelegate
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity(), AppDNADeepLinkDelegate {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppDNA.deepLinks.setDelegate(this)
// Check for deferred deep link on first launch
AppDNA.checkDeferredDeepLink { deepLink ->
if (deepLink != null) {
// User installed from a link — route to the target screen
route(deepLink.screen, deepLink.params)
// Track the visitor as a user trait
AppDNA.identify(
userId = currentUserId,
traits = mapOf("visitor_id" to deepLink.visitorId),
)
} else {
// Normal install — show default onboarding
showOnboarding()
}
}
intent?.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}
// AppDNADeepLinkDelegate
override fun onDeepLinkReceived(url: String, params: Map<String, String>) {
val path = Uri.parse(url).path ?: "/"
route(path, params)
}
private val currentUserId: String get() = "user-123"
private fun route(screen: String, params: Map<String, String>) { /* ... */ }
private fun showOnboarding() { /* ... */ }
}
Deep link routes are configured in the Console under Engagement > Deep Links. The SDK resolves deferred links by checking the Google Install Referrer plus AppDNA’s stored visitor context on first launch.