Android SDK Integration (Kotlin)
This tutorial walks you through integrating the OpenLynk SDK into a native Android app using Kotlin. By the end, your app will handle App Links, create shareable deep links, and restore deferred deep links after install.
If your project uses Java instead of Kotlin, the Java SDK is available at Android Java Reference. The API is similar but uses callback interfaces instead of coroutines.
Prerequisites
- Completed the Quick Start tutorial (you have an app with an API key)
- An Android project in Android Studio (Kotlin, API 21+)
- Your App ID and API Key from the OpenLynk dashboard
kotlinx.coroutinesin your project (most modern Android projects include this by default)
Step 1: Add the SDK
Add the OpenlynkSDK.kt file directly to your Android project. No external dependencies are required beyond the standard Android SDK and kotlinx.coroutines.
- Download
OpenlynkSDK.ktfrom the OpenLynk dashboard or repository - Place it in your project's source directory (e.g.
app/src/main/java/com/openlynk/sdk/) - Make sure the package declaration in the file matches its location
Step 2: Get Your Credentials
In the OpenLynk dashboard, navigate to your app's settings page. You need two values:
| Credential | Where to find it |
|---|---|
| App ID | App settings page, displayed at the top |
| API Key | App settings page, under "SDK API Key". Click Generate if you have not created one yet. |
Step 3: Create an Application Class
Initialize the SDK in a custom Application class so it is available throughout your app:
import android.app.Application
import com.openlynk.sdk.OpenlynkSDK
import com.openlynk.sdk.OpenlynkSDKConfig
class MyApplication : Application() {
lateinit var openlynkSDK: OpenlynkSDK
private set
override fun onCreate() {
super.onCreate()
openlynkSDK = OpenlynkSDK.create(
context = this,
appId = "YOUR_APP_ID",
apiKey = "YOUR_API_KEY",
config = OpenlynkSDKConfig(
autoRestoreOnInit = true,
userEmailProvider = {
AuthManager.getCurrentUserEmail()
},
onRestoredLinks = { links ->
for (link in links) {
val path = link.destinationPath ?: link.destinationUrl
val params = link.parameters ?: link.metadata
DeepLinkRouter.navigate(this, path, params)
}
},
onDeepLink = { parsed ->
DeepLinkRouter.navigate(
this,
parsed.destinationPath,
parsed.parameters
)
}
)
)
openlynkSDK.init()
}
}
Replace YOUR_APP_ID and YOUR_API_KEY with the real values from your dashboard. The userEmailProvider is optional but improves deferred deep link matching accuracy. If you do not have user authentication, you can omit it.
Make sure your Application class is registered in AndroidManifest.xml:
<application
android:name=".MyApplication"
... >
What Happens on init()
When you call openlynkSDK.init(), the SDK:
- Reports an install heartbeat on a background coroutine (throttled to once per 24 hours)
- If
autoRestoreOnInitistrue, calls the restore API using the email fromuserEmailProvider(or device fingerprint if no provider is set) - Calls
onRestoredLinkson the main thread if any pending links are found
Unlike Flutter, the Android SDK does not start an automatic link listener. You must call handleIncomingUri(uri) from your Activity.
Step 4: Handle App Links in MainActivity
Handle incoming App Links in both onCreate (cold start) and onNewIntent (app already running):
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.openlynk.sdk.OpenlynkSDK
class MainActivity : AppCompatActivity() {
private val sdk: OpenlynkSDK
get() = (application as MyApplication).openlynkSDK
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Handle App Link if the app was launched via a link
intent?.data?.let { uri ->
sdk.handleIncomingUri(uri)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// Handle App Link when app is already running
intent.data?.let { uri ->
sdk.handleIncomingUri(uri)
}
}
}
Step 5: Create a Deep Link Router
Create a router object that maps destination paths to activities:
import android.content.Context
import android.content.Intent
object DeepLinkRouter {
fun navigate(context: Context, path: String, params: Map<String, Any>) {
val intent = when {
path.startsWith("/product/") -> {
val productId = path.split("/").last()
Intent(context, ProductActivity::class.java).apply {
putExtra("product_id", productId)
putExtra("utm_source",
params["utm_source"]?.toString())
}
}
path.startsWith("/profile/") -> {
val userId = path.split("/").last()
Intent(context, ProfileActivity::class.java).apply {
putExtra("user_id", userId)
}
}
else -> {
Intent(context, MainActivity::class.java)
}
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
Step 6: Add the Intent Filter
Open AndroidManifest.xml and add an intent filter to your main activity with autoVerify="true":
<activity
android:name=".MainActivity"
android:exported="true">
<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="YOUR_APP_SLUG.openlynk.to" />
</intent-filter>
</activity>
Replace YOUR_APP_SLUG with your app's slug from the dashboard (e.g. myshop.openlynk.to).
The android:autoVerify="true" attribute tells Android to verify the domain ownership at install time by checking the Digital Asset Links file.
Step 7: Create a Share Button
Add a share button to an activity that creates a deep link and opens the system share sheet:
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.openlynk.sdk.OpenlynkSDK
class ProductActivity : AppCompatActivity() {
private val sdk: OpenlynkSDK
get() = (application as MyApplication).openlynkSDK
private lateinit var productId: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_product)
productId = intent.getStringExtra("product_id") ?: return
findViewById<View>(R.id.shareButton).setOnClickListener {
shareProduct()
}
}
private fun shareProduct() {
sdk.createLink(
destination = "/product/$productId",
metadata = mapOf(
"product_id" to productId,
"utm_source" to "share",
"utm_medium" to "android_app"
)
) { result ->
runOnUiThread {
result.onSuccess { link ->
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT,
"Check out this product: ${link.url}")
}
startActivity(
Intent.createChooser(shareIntent, "Share via"))
}
result.onFailure { error ->
Toast.makeText(
this,
"Could not create link: ${error.message}",
Toast.LENGTH_SHORT
).show()
}
}
}
}
}
Step 8: Get Your SHA-256 Fingerprint
Android App Links require domain verification using your signing certificate's SHA-256 fingerprint. OpenLynk uses this to generate the assetlinks.json file.
Get the Fingerprint
For debug builds:
keytool -list -v -keystore ~/.android/debug.keystore \
-alias androiddebugkey -storepass android -keypass android
For release builds:
keytool -list -v -keystore your-release-key.keystore -alias your-alias
Look for the line starting with SHA256: in the output. Copy the full fingerprint (e.g. 14:6D:E9:...).
Enter in the Dashboard
- Go to your app's settings in the OpenLynk dashboard
- Find the Android SHA-256 field
- Paste the fingerprint and save
OpenLynk will serve the Digital Asset Links file at:
https://YOUR_APP_SLUG.openlynk.to/.well-known/assetlinks.json
If you use Google Play App Signing, you need to use the deployment certificate fingerprint from the Google Play Console (Release > Setup > App signing), not the upload certificate fingerprint from your local keystore.
Step 9: Test App Links
Verify with adb
Use adb to simulate an App Link and verify your app opens:
adb shell am start -a android.intent.action.VIEW \
-d "https://YOUR_APP_SLUG.openlynk.to/YOUR_LINK_SLUG" \
com.example.myapp
Your app should launch and the onDeepLink callback should fire with the correct destination path and parameters.
Verify Domain Association
Check that Android has verified your domain:
adb shell pm get-app-links com.example.myapp
Look for your domain with a status of verified.
Test Deferred Deep Linking
- Uninstall your app from the test device
- Open your OpenLynk link in a browser on the device
- You will be redirected to the Play Store (or your web fallback)
- Reinstall and launch the app
- The
onRestoredLinkscallback should fire with the original link data
For the most reliable deferred deep link testing, stay on the same network between clicking the link and launching the app after install. The restore mechanism uses device fingerprinting and IP matching.
Exit Checklist
-
OpenlynkSDK.ktadded to the project - SDK initialized in a custom
Applicationclass -
Applicationclass registered inAndroidManifest.xml - App Links handled in
onCreateandonNewIntent - Deep link router maps paths to activities
- Intent filter added with
autoVerify="true" - Share button creates links via
createLink - SHA-256 fingerprint entered in the dashboard
- App Links tested with
adb - Deferred deep linking tested after uninstall and reinstall
What's Next?
- Android Kotlin SDK Reference -- Full API reference with all methods, configuration options, and data types.
- Handle Deep Links -- Advanced routing patterns and edge case handling.
- Push Notifications -- Register devices and send targeted push messages.
- Custom Domains -- Serve links from your own domain.