Simple on-device event tracking for Android.
Initialize the built in singleton in Application.onCreate()
.
Track.initialize(this)
Or create a new instance.
val track = Track.create(context, "my_records.db")
Track a single value (overwriting the existing one) with set()
.
Track.set("show_intro", "false")
Read it back as a record with get()
.
val record = Track.get("show_intro")
Records look like this:
data class Record(
val id: Long,
val key: String,
val timestamp: Long,
val appVersion: Long,
val value: String
)
Track multiple events per key with add()
.
Track.add("screen_visited", "settings")
Use query()
to find all records of any given key.
val allScreenVisits = Track.query("screen_visited")
You don't have to read all query results into memory.
val firstFiveVisitsToAboutScreen = Track.query("screen_visited") { records ->
records
.filter { it.value == "about" }
.take(5)
.toList() // Consume the sequence before returning
}
Track app launches and show onboarding screen only the first time.
val isFirstLaunch = Track.query("app_launched") { it.none() }
Track.add("app_launched")
if (isFirstLaunch) {
// Show onboarding screen
}
New terms of service was introduced in version 54. Show a dialog if user hasn't accepted them yet.
val lastAcceptedTosVersion = Track.get("accepted_tos")?.appVersion ?: -1
if (lastAcceptedTosVersion < 54) {
showTosScreen()
}
private fun showTosScreen() {
AlertDialog.Builder(context)
.setTitle("New TOS")
.setMessage("Bla bla bla bla...")
.setCancelable(false)
.setPositiveButton("Accept") { _, _ ->
Track.set("accepted_tos")
}
.setNegativeButton("Close app") { _, _ ->
exitProcess(0)
}
.show()
}
Ask user to rate the app under certain conditions.
val usageCount = Track.query("used_feature_x") { it.count() }
val thirtyDaysAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)
val ratedApp = Track.get("rated_app")
when {
// User still hasn't used the app much
usageCount < 5 -> return
// User never saw the rating screen
ratedApp == null -> showRatingScreen()
// User previously clicked "later" and it's been over 30 days
ratedApp.value == "later" && ratedApp.timestamp < thirtyDaysAgo -> showRatingScreen()
}
private fun showRatingScreen() {
AlertDialog.Builder(context)
.setTitle("Rate our app")
.setMessage("If you like our app, please take a second and rate it on the Play Store!")
.setPositiveButton("Rate") { _, _ ->
Track.set("rated_app", "rated")
// Open play store
}
.setNegativeButton("Never") { _, _ ->
Track.set("rated_app", "never")
}
.setNeutralButton("Later") { _, _ ->
Track.set("rated_app", "later")
}
.setOnCancelListener {
Track.set("rated_app", "later")
}
.show()
}
Track is hosted on JitPack. Here's how you include it in your gradle project:
Step 1. Add the JitPack repository to your build.gradle
or build.gradle.kts
file:
Groovy
repositories {
maven { url 'https://jitpack.io' }
}
Kotlin
repositories {
maven(url = "https://jitpack.io")
}
Step 2. Add the dependency:
Groovy
dependencies {
implementation 'com.github.gustavkarlsson:track:<latest_version>'
}
Kotlin
dependencies {
implementation("com.github.gustavkarlsson:track:<latest_version>")
}
The project contains a very simple demo app which lets you try it out very quickly. Give it a spin!