Android SDK
Native Android SDK for deep linking, mobile attribution, and conversion tracking.
Already using Claude Code, Cursor, or Claude Desktop? The LinkForty MCP server can scaffold your SDK integration automatically. Just ask: "Help me add the LinkForty SDK to my Android app."
Features
- Deferred deep linking -- route new users to specific content after install
- Direct deep linking -- handle App Links and custom URL schemes
- Install attribution -- probabilistic fingerprint matching
- Event tracking -- log in-app events tied to attribution data
- Revenue tracking -- structured purchase tracking with BigDecimal precision
- Offline event queue -- events persist across app restarts and retry automatically
- Programmatic link creation -- create short links from your app
- Privacy-first -- no GAID collection
Requirements
- Android API 26+ (Android 8.0 Oreo)
- Kotlin 1.9+
- JDK 17
Installation
Gradle (Kotlin DSL)
dependencies {
implementation("com.linkforty:sdk:1.3.0")
}
Gradle (Groovy)
dependencies {
implementation 'com.linkforty:sdk:1.3.0'
}
Quick Start
Initialize the SDK
Initialize once in your Application class or main Activity:
import com.linkforty.sdk.LinkForty
import com.linkforty.sdk.LinkFortyConfig
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val config = LinkFortyConfig(
baseURL = "https://go.yourdomain.com",
apiKey = "your-api-key", // optional -- required for link creation
appToken = "at_your_app_token", // recommended for Cloud -- enables organic-install attribution
debug = true,
attributionWindowHours = 168 // 7 days (default)
)
LinkForty.initialize(this, config)
}
}
Handle Deferred Deep Links
LinkForty.shared.onDeferredDeepLink { deepLinkData ->
if (deepLinkData != null) {
println("Attributed install: ${deepLinkData.shortCode}")
val productId = deepLinkData.customParameters?.get("productId")
if (productId != null) {
navigateToProduct(productId)
}
} else {
println("Organic install")
}
}
Handle Direct Deep Links
Pass incoming intents to the SDK from your Activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleIntent(intent)
}
private fun handleIntent(intent: Intent) {
intent.data?.let { uri ->
LinkForty.shared.handleDeepLink(uri)
}
}
}
Register a callback to receive parsed data:
LinkForty.shared.onDeepLink { url, deepLinkData ->
println("Deep link opened: $url")
deepLinkData?.let { data ->
val route = data.customParameters?.get("route")
if (route != null) {
navigateToRoute(route)
}
}
}
Track Events
// Custom event
LinkForty.shared.trackEvent(
name = "add_to_cart",
properties = mapOf("productId" to "123", "category" to "electronics")
)
// Revenue event with BigDecimal precision
LinkForty.shared.trackRevenue(
amount = BigDecimal("29.99"),
currency = "USD",
properties = mapOf("productId" to "123")
)
Every event is automatically credited to the deep link that most recently opened the app (last-click attribution), along with an app-open session — so analytics can show what users do after clicking a link. Events with no preceding deep-link open are reported as organic. No extra code is required.
Track Screen Views
Reporting screen views lets analytics build a per-link screen-flow funnel. Each screen_view carries the same last-click attribution as your other events.
Automatic (Jetpack Navigation) — attach LinkFortyNavObserver to your NavController; each destination's route (Compose) or label (XML nav graph) is reported as it appears:
import com.linkforty.sdk.navigation.LinkFortyNavObserver
navController.addOnDestinationChangedListener(LinkFortyNavObserver())
LinkFortyNavObserver requires androidx.navigation (which your app already has if it uses Jetpack Navigation); the SDK depends on it only as compileOnly.
Manual — call it yourself (e.g. for screens not driven by a NavController):
LinkForty.shared.trackScreenView("ProductDetail")
Create Links
val result = LinkForty.shared.createLink(
CreateLinkOptions(
deepLinkParameters = mapOf("route" to "PRODUCT", "id" to "123"),
title = "Check out this product",
utmParameters = UTMParameters(source = "app", medium = "share")
)
)
println(result.url) // https://go.yourdomain.com/abc123
println(result.shortCode) // abc123
Link creation requires an API key. The simplified endpoint (/api/sdk/v1/links) is only available on LinkForty Cloud, not self-hosted Core.
App Links Setup
AndroidManifest.xml
Add an intent filter to your main activity:
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<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="go.yourdomain.com" />
</intent-filter>
</activity>
Your LinkForty server automatically hosts the Digital Asset Links file at /.well-known/assetlinks.json.
Important: onNewIntent
Override onNewIntent() in your Activity to handle links when the app is already running. Without this, tapping a link while the app is in the background won't deliver the new intent data.
API Reference
Initialization
| Method | Description |
|---|---|
LinkForty.initialize(context, config) | Initialize the SDK with context and configuration |
Deep Linking
| Method | Description |
|---|---|
onDeferredDeepLink(callback) | Register callback for install attribution |
onDeepLink(callback) | Register callback for direct deep links |
handleDeepLink(uri) | Pass an incoming URI to the SDK |
Event Tracking
| Method | Description |
|---|---|
trackEvent(name, properties) | Track a custom in-app event |
trackRevenue(amount, currency, properties) | Track a revenue event (BigDecimal) |
trackScreenView(name, properties) | Report a screen view (for screen-flow funnels) |
For automatic screen tracking with Jetpack Navigation, attach LinkFortyNavObserver to your NavController instead of calling trackScreenView per screen.
Link Creation
| Method | Description |
|---|---|
createLink(options) | Create a short link programmatically |
User Identity
| Method | Description |
|---|---|
setExternalUserId(id) | Set external user ID for share attribution (pass null to clear) |
getExternalUserId() | Get the current external user ID |
Data Access
| Method | Description |
|---|---|
getInstallData() | Retrieve cached attribution data |
getInstallId() | Get the server-assigned install UUID |
Data Management
| Method | Description |
|---|---|
clearData() | Wipe all locally stored SDK data |
reset() | Return SDK to uninitialized state |
Offline Resilience
Events are automatically queued when the network is unavailable:
- Maximum queue size: 100 events
- Queue persists across app restarts
- Events are retried automatically when connectivity is restored
Privacy
The Android SDK is designed with privacy in mind:
- No GAID collection -- attribution uses probabilistic fingerprinting only
- Minimal data collection -- timezone, language, screen resolution, Android version, app version, User-Agent
- HTTPS enforced -- all communication uses HTTPS (except localhost for development)
Self-Hosted Configuration
For self-hosted LinkForty Core, omit the API key:
val config = LinkFortyConfig(
baseURL = "https://links.yourcompany.com",
apiKey = null,
debug = false
)
LinkForty.initialize(this, config)
Troubleshooting
App Links not opening the app
- Verify
android:autoVerify="true"is set on the intent filter - Check that the Digital Asset Links file is accessible at
https://go.yourdomain.com/.well-known/assetlinks.json - Test with:
adb shell am start -a android.intent.action.VIEW -d "https://go.yourdomain.com/test" - Verify app is set as default handler in Settings > Apps > Default apps
Deferred deep link not firing
- Check Logcat output (filter by "LinkForty") for install reporting errors
- Ensure the attribution window hasn't expired
- Fingerprint matching depends on network conditions -- VPNs reduce accuracy
ProGuard / R8
If you're using code shrinking, the SDK should work without additional rules. If you encounter issues, add:
-keep class com.linkforty.sdk.** { *; }
Next Steps
- Create links in the dashboard
- View analytics for your app
- Configure attribution windows
- SDK Specification -- full feature reference