Kotlin / Android SDK
Native Android analytics — app lifecycle, screen tracking, deep links, crash capture, push notifications, and A/B experiments.
The Kotlin SDK integrates directly with the Android Activity and Application lifecycle. Initialize it once from your Application class and it handles everything automatically — no manual screen calls needed for Activity-based screens.
Prerequisites
Installation
Add the dependency
dependencies {
implementation("app.flashanalytics:flashanalytics-kotlin:1.1.4")
}Sync your Gradle project after adding the dependency.
Initialize in Application.onCreate()
Initialize exactly once from your Application class so the SDK is ready before any Activity starts.
import android.app.Application
import app.flashanalytics.sdk.CaptureVariantsOptions
import app.flashanalytics.sdk.FlashAnalyticsOptions
import app.flashanalytics.sdk.android.FlashAnalyticsAndroid
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
FlashAnalyticsAndroid.init(
application = this,
options = FlashAnalyticsOptions(
appId = BuildConfig.FLASH_APP_ID, // UUID from your dashboard
captureAppLifecycle = true,
captureScreenViews = true,
captureDeepLinks = true,
captureInstallAttribution = true,
captureSessionOnInit = true,
captureNativeCrashes = true,
captureVariants = CaptureVariantsOptions(),
batchEnable = true,
batchSize = 10,
batchTimeoutMs = 5_000L,
)
)
}
}Register in AndroidManifest.xml
android:name=".MyApp" in the <application> tag.Identify users and track events
val analytics = FlashAnalyticsAndroid.getInstance()
// After login
analytics.identify(
IdentifyPayload(
profileId = "user_123",
email = "user@example.com",
)
)
// Track a product event
analytics.track("purchase_completed", mapOf(
"orderId" to "order_123",
"amount" to 49.99,
))Auto-capture flags
captureAppLifecycleapp_opened, app_foregrounded, app_backgrounded
captureSessionOnInitsdk_initialized session warm-up before lifecycle events
captureScreenViewsscreen_view on every Activity resume
captureDeepLinksdeep_link_opened for intent URLs
captureInstallAttributionInstall / update attribution
captureNativeCrashesnative_crash report on next launch
captureViewTagsAndroid View tag auto-tracking helpers
capturePushLifecyclePush notification lifecycle helpers
captureVariantsA/B experiment auto-assignment
Error tracking
try {
riskyOperation()
} catch (e: Exception) {
FlashAnalyticsAndroid.getInstance().trackError(
throwable = e,
eventName = "payment_failed",
properties = mapOf("orderId" to orderId),
)
}Deep links (warm start)
For warm-start deep links, forward the new intent from your main activity.
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
FlashAnalyticsAndroid.getInstance().onNewIntent(intent)
}Experiments
val analytics = FlashAnalyticsAndroid.getInstance()
// All cached assignments — no API call
val all = analytics.getAllExperiments()
// Cache first, API fallback (suspend)
CoroutineScope(Dispatchers.Main).launch {
val assignment = analytics.getExperimentById("checkout-cta")
println(assignment?.variantName)
}
// Callback wrapper for non-coroutine code
analytics.getExperimentByIdAsync("checkout-cta") { result ->
println(result?.variantName)
}Global properties
analytics.setGlobalProperties(mapOf(
"appVersion" to "1.2.0",
"plan" to "pro",
))Session updates
The Android SDK sends sdk_initialized on startup by default so the backend can return a session before install, update, and lifecycle events. Use onSessionUpdatedwhen native code needs the current session ID immediately after it is received or restored.
FlashAnalyticsAndroid.init(
application = this,
options = FlashAnalyticsOptions(
appId = BuildConfig.FLASH_APP_ID,
captureSessionOnInit = true,
onSessionUpdated = { session ->
Log.d("FlashAnalytics", session.id)
Log.d("FlashAnalytics", session.estimatedExpiresAt.toString())
Log.d("FlashAnalytics", session.estimatedTtlMs.toString())
},
)
)Push notifications
analytics.trackNotificationEvent(
event = FlashNotificationEvent.OPENED,
intent = intent,
source = "android_intent",
appState = "terminated",
coldStart = true,
)notificationId, messageId, campaignId, provider.Manual batch flush
// Call when the app goes to background if you manage lifecycle manually
FlashAnalyticsAndroid.getInstance().flushBatch()