Native Android SDK for deep linking, mobile attribution, and conversion tracking.
- Deferred Deep Linking: Match app installs to link clicks using privacy-compliant fingerprinting
- App Links: Full support for Android App Links (verified HTTPS deep links)
- Custom URL Schemes: Handle custom app URL schemes
- Event Tracking: Track in-app events and conversions
- Revenue Tracking: Dedicated revenue tracking with BigDecimal precision
- Offline Support: Queue events when offline with automatic retry (max 100 events)
- Programmatic Link Creation: Create short links directly from your app
- Privacy-First: No GAID collection by default
- Kotlin-Native: 100% Kotlin, modern coroutines API
- Android API 26+ (Android 8.0 Oreo)
- Kotlin 1.9+
- JDK 17
dependencies {
implementation("com.linkforty:sdk:1.0.0")
}dependencies {
implementation 'com.linkforty:sdk:1.0.0'
}In your Application class or main Activity:
import com.linkforty.sdk.LinkForty
import com.linkforty.sdk.models.LinkFortyConfig
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
lifecycleScope.launch {
try {
val config = LinkFortyConfig(
baseURL = "https://go.yourdomain.com",
apiKey = "your-api-key", // Optional for self-hosted
debug = true,
attributionWindowHours = 168 // 7 days
)
val response = LinkForty.initialize(this@MyApplication, config)
Log.d("LinkForty", "Install ID: ${response.installId}")
} catch (e: Exception) {
Log.e("LinkForty", "Initialization failed", e)
}
}
}
}LinkForty.shared.onDeferredDeepLink { deepLinkData ->
if (deepLinkData != null) {
// User installed from a link - navigate to content
Log.d("LinkForty", "Install attributed to: ${deepLinkData.shortCode}")
Log.d("LinkForty", "UTM Source: ${deepLinkData.utmParameters?.source}")
// Navigate to the right content
deepLinkData.customParameters?.get("productId")?.let { productId ->
navigateToProduct(productId)
}
} else {
// Organic install - no attribution
Log.d("LinkForty", "Organic install")
}
}First, configure App Links in your AndroidManifest.xml:
<activity android:name=".MainActivity">
<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>Then handle incoming intents:
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 callback
LinkForty.shared.onDeepLink { uri, deepLinkData ->
Log.d("LinkForty", "Deep link opened: $uri")
deepLinkData?.let { data ->
Log.d("LinkForty", "Link data: $data")
data.deepLinkPath?.let { path ->
navigateToPath(path)
}
}
}Server-side resolution: When the SDK is initialized, deep links are automatically resolved via the server to provide enriched data including
deepLinkPath,appScheme, andlinkId. If the server is unreachable, the SDK falls back to local URL parsing.
// Track a simple event
LinkForty.shared.trackEvent("button_clicked")
// Track event with properties
LinkForty.shared.trackEvent(
name = "purchase",
properties = mapOf(
"product_id" to "123",
"amount" to 29.99,
"currency" to "USD"
)
)
// Track revenue
LinkForty.shared.trackRevenue(
amount = BigDecimal("29.99"),
currency = "USD",
properties = mapOf("product_id" to "123")
)val result = LinkForty.shared.createLink(
CreateLinkOptions(
deepLinkParameters = mapOf("route" to "VIDEO_VIEWER", "id" to "vid123"),
title = "Check this out!",
utmParameters = UTMParameters(source = "app", campaign = "share")
)
)
Log.d("LinkForty", "Share this link: ${result.url}")
// e.g., "https://go.yourdomain.com/tmpl/abc123"Note: Requires an API key in
LinkFortyConfig. See API Reference for all options.
val config = LinkFortyConfig(
baseURL = "https://links.yourcompany.com",
apiKey = null // No API key needed for self-hosted
)
LinkForty.initialize(context, config)val config = LinkFortyConfig(
baseURL = "https://go.yourdomain.com",
attributionWindowHours = 24 // 1 day instead of default 7 days
)LinkForty.shared.getInstallData()?.let { data ->
Log.d("LinkForty", "Short code: ${data.shortCode}")
Log.d("LinkForty", "UTM source: ${data.utmParameters?.source}")
}
LinkForty.shared.getInstallId()?.let { id ->
Log.d("LinkForty", "Install ID: $id")
}// Check queued events count
val count = LinkForty.shared.queuedEventCount
// Manually flush event queue
LinkForty.shared.flushEvents()
// Clear event queue
LinkForty.shared.clearEventQueue()LinkForty.shared.clearData()
// Reset SDK to uninitialized state
LinkForty.shared.reset()Your backend must serve a Digital Asset Links file at:
https://go.yourdomain.com/.well-known/assetlinks.json
Example:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourcompany.yourapp",
"sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
}
}]Add an intent filter to your main activity (see Quick Start section).
# Verify Digital Asset Links
adb shell am start -a android.intent.action.VIEW \
-d "https://go.yourdomain.com/abc123" \
com.yourcompany.yourapp- No GAID: Does not collect Google Advertising ID by default
- No Persistent IDs: Uses probabilistic fingerprinting only
- Data Minimization: Collects only necessary attribution data
- User Control: Provides
clearData()for user data deletion
- Device timezone
- Device language
- Screen resolution (pixels)
- Android version
- App version
- User-Agent string
The SDK enforces HTTPS for all API endpoints (except localhost, 127.0.0.1, and 10.0.2.2 for development).
./gradlew sdk:testDebugUnitTest./gradlew sdk:lintDebug./gradlew sdk:assembleReleaseThis SDK requires a running LinkForty backend:
- LinkForty Core (open source): Self-host for free
- LinkForty Cloud (SaaS): Managed service with advanced features
See: https://github.com/linkforty/core
- Documentation: https://docs.linkforty.com
- Issues: https://github.com/LinkForty/mobile-sdk-android/issues
See CHANGELOG.md for version history.
LinkForty Android SDK is available under the MIT license. See LICENSE for more info.
- LinkForty Core - Open source deep linking backend
- LinkForty iOS SDK - iOS SDK
- LinkForty React Native SDK - React Native integration
Made with care by the LinkForty team