Android deferred deep linking enables your app to deliver personalized onboarding experiences by capturing user intent before installation and applying it after the app is first launched. The Install Referrer API is Google's recommended mechanism for implementing this functionality, providing a secure and reliable way to pass attribution data from pre-install clicks to post-install app sessions.
This guide covers everything you need to know about configuring Android deferred deep links using the Install Referrer API, including implementation strategies, best practices, and common pitfalls to avoid.
Understanding the Install Referrer API
The Google Play Install Referrer API allows apps to retrieve referral content that initiated an app installation from Google Play. When a user clicks a link before your app is installed, the referrer information is stored by Google Play and made available to your app after installation.
Key advantages of the Install Referrer API include:
Security: Direct communication with Google Play Store eliminates broadcast vulnerabilities
Reliability: More accurate than legacy broadcast receivers with guaranteed delivery
Persistence: Referrer data remains available for up to 90 days after installation
Fraud Prevention: Includes click timestamp and install begin timestamp for attribution validation
Prerequisites for Implementation
Before implementing deferred deep linking with Install Referrer, ensure you have:
Android app published on Google Play Store or in testing tracks
Minimum SDK version 14 (Ice Cream Sandwich) or higher
Google Play Services installed on target devices
Step 1: Add Install Referrer Library Dependency
Add the Google Play Install Referrer library to your app's build.gradle file:
dependencies {
implementation 'com.android.installreferrer:installreferrer:2.2'
}
This library provides the necessary APIs to query install referrer information from Google Play.
Step 2: Create the Referrer Client
Implement the Install Referrer connection in your main Activity or Application class. Here's a complete implementation:
import android.os.Bundle
import android.os.RemoteException
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener
import com.android.installreferrer.api.ReferrerDetails
class MainActivity : AppCompatActivity() {
private lateinit var referrerClient: InstallReferrerClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupInstallReferrer()
}
private fun setupInstallReferrer() {
referrerClient = InstallReferrerClient.newBuilder(this).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
// Connection established
handleReferrerDetails()
}
InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED -> {
// API not available on the current Play Store app
Log.w(TAG, "Install Referrer not supported")
}
InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE -> {
// Connection couldn't be established
Log.w(TAG, "Install Referrer service unavailable")
}
}
}
override fun onInstallReferrerServiceDisconnected() {
// Try to restart the connection on the next request
Log.d(TAG, "Install Referrer service disconnected")
}
})
}
private fun handleReferrerDetails() {
try {
val response: ReferrerDetails = referrerClient.installReferrer
val referrerUrl = response.installReferrer
val referrerClickTime = response.referrerClickTimestampSeconds
val appInstallTime = response.installBeginTimestampSeconds
val instantExperienceLaunched = response.googlePlayInstantParam
// Hit smler endpoint to mark as conversion
processDeferredDeepLink(referrerUrl)
} catch (e: RemoteException) {
Log.e(TAG, "Error retrieving referrer details", e)
} finally {
referrerClient.endConnection()
}
}
companion object {
private const val TAG = "MainActivity"
}
}
You can read more about tracking conversion to know when and how to track a conversion
Step 3: Parse Referrer String and Extract Deep Link
Create a utility function to parse the referrer string and extract your deep link destination:
You can see an example of how to do it in our github flutter sdk
Step 4: Handle First Launch Detection
Critical to deferred deep linking is ensuring the experience only triggers on the first launch after installation. Implement robust first-launch detection using SharedPreferences or a more sophisticated solution:
class FirstLaunchManager(private val context: Context) {
private val prefs =
context.getSharedPreferences("deep_link_prefs", Context.MODE_PRIVATE)
companion object {
private const val KEY_FIRST_LAUNCH = "is_first_launch"
private const val KEY_INSTALL_TIME = "install_timestamp"
private const val KEY_REFERRER_PROCESSED = "referrer_processed"
}
fun isFirstLaunch(): Boolean {
// Check if this is truly the first launch
val isFirst = prefs.getBoolean(KEY_FIRST_LAUNCH, true)
val referrerProcessed = prefs.getBoolean(KEY_REFERRER_PROCESSED, false)
return isFirst && !referrerProcessed
}
fun markReferrerProcessed() {
prefs.edit()
.putBoolean(KEY_FIRST_LAUNCH, false)
.putBoolean(KEY_REFERRER_PROCESSED, true)
.putLong(KEY_INSTALL_TIME, System.currentTimeMillis())
.apply()
}
fun shouldRetryReferrerFetch(): Boolean {
val installTime = prefs.getLong(KEY_INSTALL_TIME, 0)
val daysSinceInstall =
(System.currentTimeMillis() - installTime) / (1000 * 60 * 60 * 24)
// Retry if within 90 days and not yet processed
return daysSinceInstall < 90 &&
!prefs.getBoolean(KEY_REFERRER_PROCESSED, false)
}
}
Best Practices for Install Referrer Implementation
Timing Considerations
The Install Referrer API should be called as early as possible in your app's lifecycle, but with important considerations:
Don't block the UI: Fetch referrer data asynchronously to avoid delaying app launch
Implement timeouts: Set a maximum wait time (2-3 seconds) for referrer retrieval
Cache results: Store referrer data locally after first retrieval to avoid repeated queries
Handle delays gracefully: Some devices may have delayed Google Play connections
Testing Your Implementation
Testing deferred deep links requires special procedures since they only work on first install:
Use Internal Testing Track: Publish your app to Google Play's internal testing track
Generate Test Links: Create Play Store links with test referrer parameters
Test Device Preparation: Completely uninstall the app before each test
Click Test Link: Click your test link on the device
Install and Launch: Complete installation and observe first launch behavior
Verify Logs: Check logcat for referrer retrieval and parsing logs
For easier testing during development, create a debug mode that simulates first launch:
// Debug utility for testing
fun simulateFirstLaunch() {
if (BuildConfig.DEBUG) {
getSharedPreferences("deep_link_prefs", Context.MODE_PRIVATE).edit().clear().apply()
}
}
Published with LeafPad