Android and JVM (Kotlin)
Two packages, for Kotlin or Java:
glancy-androidfor Android apps (API 21+): events, screen views, app lifecycle and an offline queue.glancy-core, the same client for any JVM: Kotlin or Java backends, workers and command-line tools. No dependencies.
Install
The packages are published to GitHub Packages, which asks for a GitHub token even for reading. Create a
personal access token with the read:packages scope and put it in
~/.gradle/gradle.properties (not in your project):
gpr.user=your-github-username
gpr.key=ghp_your_token
Then add the repository and the dependency:
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://maven.pkg.github.com/caravela-labs/glancy") {
credentials {
username = providers.gradleProperty("gpr.user").orNull
password = providers.gradleProperty("gpr.key").orNull
}
}
}
}
// app/build.gradle.kts
dependencies {
implementation("com.glancy:glancy-android:0.1.3") // or glancy-core on any JVM
}
Set up (Android)
Call setup in your Application class, with the write key from your bucket's Setup page:
class KitboxApp : Application() {
override fun onCreate() {
super.onCreate()
Glancy.setup(this, writeKey = "YOUR_WRITE_KEY", host = "https://ingest.heyglancy.com")
}
}
Remember to register the class in AndroidManifest.xml (<application android:name=".KitboxApp" …>). The library
adds the INTERNET permission itself.
Events, screens and users
Glancy.track("Order Completed", mapOf("revenue" to 42, "currency" to "EUR"))
// after sign in
Glancy.identify(user.id, mapOf("name" to user.name, "email" to user.email))
// on sign out
Glancy.reset()
Send screen views with screen, for example from a Compose screen:
@Composable
fun CheckoutScreen() {
LaunchedEffect(Unit) { Glancy.screen("Checkout") }
// …
}
For apps built on Activities, Glancy.setup(this, writeKey, host, trackActivities = true) sends a screen view for
every Activity instead, named after its class (without "Activity").
App lifecycle
On by default:
| Event | When |
|---|---|
Application Installed |
The first launch |
Application Updated |
The first launch after versionName or versionCode changed |
Application Opened |
Each launch, and each return to the foreground (from_background: true) |
Application Backgrounded |
The app goes to the background; the queue is sent right away |
Every event also carries the manufacturer, model, Android version, screen size, locale, time zone and app version.
Options
Glancy.setup(this, writeKey = "YOUR_WRITE_KEY", host = "https://ingest.heyglancy.com") {
flushAt = 20 // events per batch
flushIntervalMs = 30_000 // time between batches
maxQueueSize = 1000 // events kept while offline
trackLifecycle = true
debug = BuildConfig.DEBUG // log every event
}
Events waiting to be sent are kept in the app's files (filesDir/glancy), so they survive restarts and time
offline.
Any JVM (glancy-core)
On a server, create one client, give it a folder for its queue, and shut it down cleanly so queued events are sent:
val glancy = GlancyClient(
GlancyConfig(writeKey = "YOUR_WRITE_KEY", host = "https://ingest.heyglancy.com"),
FileStorage(File("/var/lib/myapp/glancy")),
)
glancy.identify("user_42")
glancy.track("Invoice Paid", mapOf("amount" to 120))
Runtime.getRuntime().addShutdownHook(Thread { glancy.shutdown() })
Use the same user ids as your apps, and server events land on the same people.