Deep Links
Handle Android App Links to route taps into the right screen, with cold start and warm start covered by the WarpLink SDK.
When a user taps a WarpLink URL and your app is installed, Android opens your Activity via App Links. The SDK resolves the URI into a WarpLinkDeepLink with the destination, custom parameters, and attribution data, then delivers it to the onLink callback you passed to configure().
Handle Incoming Links
configure() auto-registers ActivityLifecycleCallbacks, so cold start is automatic: a link that launches your app resolves and dispatches to onLink with no per-Activity code. Warm start (a link arriving while the app already runs) needs one line, because Android delivers it through onNewIntent. Both paths are gated by automaticDeepLinks, so opting out turns off the whole automatic model, not just cold start.
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import app.warplink.WarpLink
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Cold start is handled automatically by the SDK.
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
WarpLink.onNewIntent(intent) // warm start: one line
}
}import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import app.warplink.WarpLink
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { MyApp() }
// Cold start is handled automatically by the SDK.
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
WarpLink.onNewIntent(intent) // warm start: one line
}
}Set android:launchMode="singleTask" on the Activity so warm-start links reuse the running instance. Resolved links arrive in your onLink callback, always on the main thread.
Cold Start vs Warm Start
| Scenario | Entry Point | Behavior |
|---|---|---|
| Cold start | App not running: system launches Activity | Handled automatically. The link resolves and onLink fires |
| Warm start | App in background: brought to foreground | onNewIntent() forwards the intent via WarpLink.onNewIntent, then onLink fires |
Working with Deep Link Data
Your onLink callback receives a WarpLinkDeepLink:
WarpLinkOptions(onLink = { result ->
result.onSuccess { deepLink ->
Log.d("MyApp", "Link ID: ${deepLink.linkId}")
Log.d("MyApp", "Destination: ${deepLink.destination}")
Log.d("MyApp", "Deferred: ${deepLink.isDeferred}")
// Android-specific deep link URL
deepLink.deepLinkUrl?.let { url ->
navigateToPath(url)
}
// Custom parameters
val productId = deepLink.customParams["product_id"] as? String
productId?.let { showProduct(it) }
}
})
Manual Resolution (Advanced)
To drive resolution yourself, set automaticDeepLinks = false in WarpLinkOptions and call handleDeepLink with the URI from intent?.data:
intent?.data?.let { uri ->
WarpLink.handleDeepLink(uri) { result ->
result.onSuccess { deepLink -> navigateTo(deepLink.destination) }
}
}
Error Handling
result.onFailure { error ->
when (error) {
is WarpLinkError.NotConfigured ->
Log.e("MyApp", "Call configure() first")
is WarpLinkError.InvalidUrl ->
Log.e("MyApp", "Not a WarpLink URL")
is WarpLinkError.LinkNotFound ->
showLinkExpired()
is WarpLinkError.NetworkError ->
showOfflineMessage()
is WarpLinkError.ServerError ->
Log.e("MyApp", "Server error ${error.statusCode}: ${error.message}")
else ->
Log.e("MyApp", "Error: ${error.message}")
}
}
Verify assetlinks.json
WarpLink generates the Digital Asset Links file automatically. Verify it:
curl https://aplnk.to/.well-known/assetlinks.json
Check App Links verification status:
adb shell pm get-app-links com.yourcompany.yourapp
If App Links aren't verified, try uninstalling and reinstalling the app. Android re-verifies assetlinks.json at install time.