Android SDK - Supporting Deep Links

Adding Deep Linking Support

Deep links direct users to specific content within your app. When users tap a deep link on a device with your app installed, the app opens directly to the intended content, such as a product page or specific experience.

Singular tracking links support both standard deep linking (for installed apps) and deferred deep linking (for new installs). For comprehensive information, see the Deep Linking FAQ and Singular Links FAQ .


Requirements

Prerequisites

Complete the Singular Links Prerequisites to enable deep linking for your app.


Implement Singular Links Handler

The SingularLinkHandler provides a callback mechanism to retrieve deep link, deferred deep link, and passthrough parameters from Singular tracking links when the app opens.

Available Parameters:

  • Deep Link (_dl): The destination URL within your app for users clicking the link
  • Deferred Deep Link (_ddl): The destination URL for users who install the app after clicking the link
  • Passthrough (_p): Custom data passed through the tracking link for additional context

SDK Configuration

Configure AndroidManifest

Before the SDK can resolve a deep link, your activity must declare an intent filter so Android routes incoming ACTION_VIEW intents to it. Add the filter to the launcher activity (or whichever activity should receive deep links) in AndroidManifest.xml and substitute your own scheme and host.

<activity
    android:name=".MainActivity"
    android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

    <!-- Custom URI scheme deep link -->
    <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="yourapp" />
    </intent-filter>

    <!-- HTTPS Singular Link (replace with your branded subdomain) -->
    <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="http" />
        <data android:scheme="https" />
        <data android:host="yourcompany.sng.link" />
        <data android:pathPrefix="/A"/>
        <data android:pathPrefix="/B"/>
        <data android:pathPrefix="/E"/>
        <data android:pathPrefix="/F"/>
    </intent-filter>
</activity>

Without these intent filters the OS will not deliver the deep link intent to your activity and the SingularLinkHandler callback will not fire. App Links (HTTPS scheme with android:autoVerify="true" ) also require a hosted /.well-known/assetlinks.json file on the destination domain.


Add SingularLinkHandler to Config

Configure the SingularLinkHandler during SDK initialization to process incoming deep link and deferred deep link data.

Kotlin Java
private fun initSingularSDK() {
    val config = SingularConfig("SDK_KEY", "SDK_SECRET")
        .withSingularLink(intent) { params ->
            val deeplink = params.deeplink
            val passthrough = params.passthrough
            val isDeferred = params.isDeferred

            Log.d("SingularLink", "Deeplink: ${deeplink ?: "null"}")
            Log.d("SingularLink", "Passthrough: ${passthrough ?: "null"}")
            Log.d("SingularLink", "Is Deferred: $isDeferred")
            
            // Handle deep link routing
            deeplink?.let { url ->
                handleDeepLink(url, isDeferred)
            }
        }

    try {
        Singular.init(applicationContext, config)
        Log.d("Singular", "SDK initialized successfully")
    } catch (e: Exception) {
        Log.e("Singular", "SDK initialization failed: ${e.message}")
    }
}

override fun onNewIntent(intent: Intent?) {
  super.onNewIntent(intent)
  // Configure onNewIntent to handle Warm start deeplinks
  intent?.let {
    setIntent(intent)
    initSingularSDK()
  }
}

Note: The SingularLinkHandler is triggered only when the app opens through a Singular Link. For more information, see the Singular Links FAQ .

withSingularLink defaults to a 10-second short link resolution timeout when called without the shortlinkTimeoutSec argument. To override it, use the three-argument overload withSingularLink(Intent intent, SingularLinkHandler handler, long shortlinkTimeoutSec) . When the intent action is ACTION_VIEW , the SDK also marks the session as opened with a deep link, which affects attribution.


Handler Behavior

The SingularLinkHandler behaves differently depending on whether the app is freshly installed or already installed.

Fresh Install (Deferred Deep Link)

On a fresh install, no Open URL exists when the app launches. Singular completes attribution to determine if the tracking link contained a deep link or deferred deep link value.

Deferred Deep Link Flow:

  1. User clicks a Singular tracking link configured with a deep link value
  2. User installs and opens the app for the first time
  3. Singular SDK sends the first session to Singular servers
  4. Attribution completes and identifies the deep link from the tracking link
  5. Deep link value returns to the SingularLinkHandler in the deeplink parameter with isDeferred = true

Testing Deferred Deep Links:

  1. Uninstall the app from the test device (if currently installed)
  2. Reset your Google Advertising ID (GAID) on the device
  3. Click the Singular tracking link from the device (ensure it's configured with a deep link value)
  4. Install and open the app

Attribution should complete successfully, and the deferred deep link value will be passed to the SingularLinkHandler.

Pro Tip: When testing deep links with a development build using a different package name (e.g., com.example.dev instead of com.example.prod ), configure the tracking link specifically for the development app's package name. After clicking the test link, install the development build directly onto the device via Android Studio or APK, rather than downloading the production app from the app store.


Already Installed (Immediate Deep Link)

When the app is already installed, clicking a Singular Link opens the app immediately using Android App Links technology.

Immediate Deep Link Flow:

  1. User clicks a Singular tracking link
  2. Android OS provides an Open URL containing the entire Singular tracking link
  3. During SDK initialization, Singular parses the Android Intent
  4. Singular extracts the deeplink and passthrough values
  5. Values return through the SingularLinkHandler with isDeferred = false

Passthrough Parameters

Capture additional data from the tracking link click using passthrough parameters.

If a passthrough (_p) parameter is included in the tracking link, the SingularLinkHandler's passthrough parameter contains the corresponding data. Use this for capturing campaign metadata, user segmentation data, or any custom information you need in the app.

Kotlin Java
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withSingularLink(intent) { params ->
        // Extract passthrough data
        params.passthrough?.let { passthroughData ->
            try {
                // Parse and use custom data
                val jsonData = JSONObject(passthroughData)
                val campaignId = jsonData.optString("campaign_id")
                val userSegment = jsonData.optString("segment")

                Log.d("SingularLink", "Campaign ID: $campaignId")
                Log.d("SingularLink", "User Segment: $userSegment")
            } catch (e: JSONException) {
                Log.e("SingularLink", "Error parsing passthrough data", e)
            }
        }
    }

Forward All Query Parameters

Capture all query parameters from the tracking link URL by appending the _forward_params=2 parameter.

When _forward_params=2 is added to the tracking link, all query parameters are included in the deeplink parameter of the SingularLinkHandler, giving you access to the complete URL with all its parameters.

Example Tracking Link:
https://yourapp.sng.link/A1b2c/abc123?_dl=myapp://product/123&_forward_params=2&utm_source=facebook&promo=SALE2024

The SingularLinkHandler will receive:
deeplink = "myapp://product/123?utm_source=facebook&promo=SALE2024"