DLinkClick
Documentation

AmiLink Integration Guide

A lightweight, dependency-free integration approach. Copy-paste our native helpers to handle URL resolution, capture attribution events, and report real-time analytics.

1. Register Your App

Create an Application in your dashboard and specify Android/iOS details.

2. Domain verification

AmiLink auto-hosts assetlinks.json & apple-app-site-association files.

3. Native Analytics SDK

Embed the helper class below to fetch deferred redirects and report analytics.

Android Native SDK Code

Enable Android App Links and copy-paste the Kotlin helper class below to handle routing, deferred attribution, and analytics event logging.

1

Add App Link Intent Filter

Add this intent-filter inside the main activity tag of your AndroidManifest.xml:

AndroidManifest.xml
<!-- AndroidManifest.xml — inside your <activity> tag -->
<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" />

    <!-- Use your verified custom domain from the AmiLink dashboard -->
    <data android:scheme="https" android:host="your-custom-domain.com" />
</intent-filter>
2

Create AmiLink.kt Helper Class

Add the full SDK class to your codebase for deferred attribution and automatic analytics reporting:

AmiLink.kt
package com.amilink.sdk

import android.content.Context
import android.os.Build
import android.provider.Settings
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException

/**
 * AmiLink Android SDK / Helper
 * 
 * Lightweight implementation to handle Android App Links, Deferred Deep Linking,
 * and background analytics reporting.
 */
object AmiLink {

    private var workspaceId: String? = null
    private val client = OkHttpClient()
    private const val apiBase = "https://api.amilink.to/sdk" // AmiLink production API

    /**
     * Configure the SDK
     */
    fun configure(workspaceId: String) {
        this.workspaceId = workspaceId
    }

    /**
     * Handle incoming App Links in your MainActivity
     */
    fun handle(data: android.net.Uri?) {
        data?.let {
            val slug = it.lastPathSegment ?: return
            reportEvent(EventType.OPEN, slug)
        }
    }

    /**
     * Check for deferred deep links on first cold start
     */
    fun checkDeferred(context: Context, callback: (JSONObject?) -> Unit) {
        val appId = context.packageName
        val fingerprint = Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
        
        val json = JSONObject().apply {
            put("applicationId", appId)
            put("fingerprint", fingerprint)
            put("platform", "Android")
            put("os", "Android ${Build.VERSION.RELEASE}")
        }

        val request = Request.Builder()
            .url("$apiBase/deferred")
            .post(json.toString().toRequestBody("application/json".toMediaType()))
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                callback(null)
            }

            override fun onResponse(call: Call, response: Response) {
                val body = response.body?.string() ?: return callback(null)
                val responseJson = JSONObject(body)
                if (responseJson.optBoolean("match")) {
                    callback(responseJson.optJSONObject("data"))
                } else {
                    callback(null)
                }
            }
        })
    }

    /**
     * Report analytics events (OPEN, INSTALL, CONVERSION)
     */
    fun reportEvent(eventType: EventType, deepLinkSlug: String) {
        val json = JSONObject().apply {
            put("eventType", eventType.name)
            put("deepLinkId", deepLinkSlug)
            put("platform", "Android")
            put("os", "Android ${Build.VERSION.RELEASE}")
        }

        val request = Request.Builder()
            .url("$apiBase/events")
            .post(json.toString().toRequestBody("application/json".toMediaType()))
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {}
            override fun onResponse(call: Call, response: Response) {}
        })
    }
}

enum class EventType {
    OPEN, INSTALL, CONVERSION
}