Skip to content
Docs
Browse Developers

Android SDK

Install kontala-android from Maven Central and capture screens, taps and events in your Android app, built with Views or Jetpack Compose.

kontala-android captures what people do in your native Android app, built with Views or Jetpack Compose, in Kotlin or Java, the way the website tag captures a site. It records every screen they see, every control they tap, who signs in, what forms and searches sent, how far they scrolled, where they struggled, how fast each screen was, and your app's own events.

Requirements

  • Android 7.0 (API 24) or later.
  • An app compiled against Android 16 (API 36) or later, as Google Play asks of every app update.
  • For a Kotlin app, Kotlin 2.0 or later. A Java app needs nothing more.

The SDK reads AndroidX Fragments, Jetpack Navigation and Jetpack Compose where your app has them, and needs none of them.

1. Find your write key

Open the property in Kontala and find its Events API card. It shows the property's write key (pk_live_...) and the Events API URL to send to.

The write key is public: every copy of your app carries it, as every page carries the tag's. Never put a server key (ksk_live_...) in an app.

2. Add the library

Add it to your app module's build.gradle.kts:

dependencies {
    implementation("la.konta:kontala-android:0.1.0")
}

It is on Maven Central, and its two dependencies, Google Play services' advertising ID and App Set ID libraries, are on Google's repository. Both are the repositories Android Studio puts in every new project's settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}

3. Start it

Call Kontala.init in your Application.onCreate, before any activity:

class ShopApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Kontala.init(this, writeKey = "pk_live_...", endpoint = "https://konta.la/v1/events")
    }
}
public class ShopApp extends Application {
    @Override public void onCreate() {
        super.onCreate();
        Kontala.init(this, "pk_live_...", "https://konta.la/v1/events");
    }
}

The application class is the one your manifest names (<application android:name=".ShopApp">). Use the write key and endpoint from your property's Events API card. Activities, fragments and Navigation destinations are screens by themselves, so nothing else is configured per screen.

Every other Kontala method may be called from any thread, and before init: those calls are kept and applied in order.

4. Platform setup

No setup is needed. The SDK adds the INTERNET permission and the AD_ID permission, so declare advertising ID use in Play Console.

If your app must not use the advertising ID, for example in Google Play's Families programme, remove the permission in your own manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
  <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" />
</manifest>

R8

The SDK's own R8 rules come with it, so a minified app needs none for it to work. To name screens by their class in a minified build, where nothing else names them, keep the class names:

-keepnames class * extends android.app.Activity
-keepnames class * extends androidx.fragment.app.Fragment

5. Check that it works

Start the app with debug logging on:

Kontala.init(
    this,
    writeKey = "pk_live_...",
    endpoint = "https://konta.la/v1/events",
    options = KontalaOptions(debug = true),
)

The log, under the tag Kontala (adb logcat -s Kontala), shows every event as it is captured, and every event the API refused, with its reason.

A debuggable build, and any build in an emulator, marks its events as a developer's. Kontala leaves them out of visitor counts by default, as it does for a development server.

Optional setup

Name screens and mark controls

OnMarkerDoes
An activity or a fragmentKontalaScreenDeclares the screen it shows: its name, page type and data
A viewview.kontalaEvent = KontalaClickType.ADD_TO_CARTDeclares the click type of a control, or of every control in it
A viewview.kontalaMask = trueA tap in it is sent as its role alone: no id, label, text or class
A viewview.kontalaIgnore = trueNothing in it is captured
A composableModifier.kontalaEvent(...), .kontalaMask(), .kontalaIgnore()The same, for what the composable draws

A Compose app using Navigation hands its controller over with KontalaNavigation.track(navController). A text field never sends what is typed into it.

Identify signed-in users

Kontala.identify(user = "customer-42", org = "acme", traits = mapOf("plan" to "pro"))

Every later event carries the user and organisation. Call Kontala.identify() with neither to log out, or Kontala.reset() to also forget the install and session.

Track your own events

Kontala.track("wishlisted", mapOf("product_id" to "42"))

Custom events arrive while the property's data layer captures the Events API's events.

The SDK starts with consent granted. To wait for your consent banner instead, start undecided and answer when the visitor chooses:

Kontala.init(
    this,
    writeKey = "pk_live_...",
    endpoint = "https://konta.la/v1/events",
    options = KontalaOptions(consent = KontalaConsent.UNKNOWN),
)

// Later, from your banner:
Kontala.consent(KontalaConsent.GRANTED)

Kontala.optOut(true) stops all capture, sending and storage on the device, across launches. See Consent for how Kontala treats each state.

Web pages in the app

If your app shows pages of your website in a WebView, the SDK shares its visitor and visit with them through the WebView cookie store, so one person is counted once. Attach a WebView for the closest link: the page then takes the app's consent and signed-in user.

class HelpActivity : Activity() {
    private lateinit var attachment: KontalaWebViewAttachment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val webView = WebView(this).apply { settings.javaScriptEnabled = true }
        attachment = Kontala.attachWebView(webView)
        setContentView(webView)
        webView.loadUrl("https://shop.example.com/help")
    }

    override fun onDestroy() {
        attachment.detach()
        super.onDestroy()
    }
}

Attach a WebView before its first page loads, and call detach() when it goes.

Troubleshooting

  • Screens are missing from a release build. R8 renamed their classes: declare each with KontalaScreen, or keep the class names (see R8).
  • Every screen is the one activity. A single-activity app names its screens through Navigation, KontalaNavigation.track, or Kontala.screen.
  • No taps arrive. Turn clicks on for the property in Kontala.
  • No custom events arrive. The property's data layer is off, or its capture rules do not include the Events API.
  • Every row reads as a developer's. It is a debuggable build, or an emulator.
  • Nothing arrives at all. The write key is wrong or revoked, or the app cannot reach the endpoint. Events wait in the app's queue until it can.

Google Play data safety form

What the SDK sends is yours to declare in Google Play's data safety form:

Data safety formWhat the SDK sends
Device or other IDsA random install id; on consented events, Android ID, App Set ID and advertising ID
Personal info: User IDsThe ids Kontala.identify names
Personal info: Email addressThe email a login names
App activity: App interactionsScreens, taps, swipes, scroll depth, time on screen and your events
App activity: In-app search historyWhat a search looked for
App activity: Other user-generated contentWhat your app's forms sent
App info and performance: Crash logsExceptions your app did not catch
App info and performance: DiagnosticsRage and dead taps
App info and performance: Other app performance dataHow fast each screen was
Location: Approximate locationCountry, region and city, derived from each request's address

Each is used for analytics and linked to the user where your app identifies them. None is used for advertising: the advertising ID goes to Kontala alone and is never joined with another company's data.

Licence

The SDK is provided under the Kontala SDK License.

Was this helpful?