Hero
Back to all guides

How to add analytics to Android apps

Add privacy-first analytics to Android applications using OpenPanel's Kotlin SDK. Track events, identify users, and analyze behavior.

OpenPanel Team

12/15/2025

Intermediate
10 min

How to add analytics to Android apps

This guide walks you through adding OpenPanel analytics to an Android application using the Kotlin SDK. You'll learn how to track events, identify users, and monitor screen views across your app.

OpenPanel works well for Android apps because it provides a lightweight, privacy-focused SDK that handles offline queuing and automatic system information collection. Unlike web SDKs, native apps require a client secret for authentication since CORS headers aren't available.

Prerequisites

  • An Android project (minSdkVersion 21+)
  • An OpenPanel account
  • Your Client ID and Client Secret from the dashboard

Add the dependency

Start by adding the OpenPanel SDK to your app's build.gradle.kts file. The SDK is available through standard Gradle dependency management.

dependencies {
    implementation("dev.openpanel:openpanel:0.0.1")
}

The Kotlin SDK is currently in development, so check the GitHub repository for the latest version number before adding it to your project.

Initialize OpenPanel

Before you can track events, you need to initialize OpenPanel in your Application class. This ensures the SDK is available throughout your app and can properly manage its lifecycle.

import android.app.Application
import dev.openpanel.OpenPanel

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        OpenPanel.create(
            context = this,
            options = OpenPanel.Options(
                clientId = "YOUR_CLIENT_ID",
                clientSecret = "YOUR_CLIENT_SECRET"
            )
        )
    }
}

You also need to register your Application class in the Android manifest so the system knows to use it.

<application
    android:name=".MyApplication"
    ...>
</application>

If you're using dependency injection with Hilt or Dagger, you can provide OpenPanel as a singleton instead. This approach integrates better with modern Android architecture patterns.

import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dev.openpanel.OpenPanel
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Provides
    @Singleton
    fun provideOpenPanel(@ApplicationContext context: Context): OpenPanel {
        return OpenPanel.create(
            context,
            OpenPanel.Options(
                clientId = "YOUR_CLIENT_ID",
                clientSecret = "YOUR_CLIENT_SECRET"
            )
        )
    }
}

Track events

Once OpenPanel is initialized, you can track events anywhere in your app by getting the SDK instance and calling the track method. Each event has a name and an optional map of properties.

import dev.openpanel.OpenPanel

class MainActivity : AppCompatActivity() {
    private lateinit var op: OpenPanel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        op = OpenPanel.getInstance(this)
        
        findViewById<Button>(R.id.signupButton).setOnClickListener {
            op.track(
                "button_clicked",
                mapOf(
                    "button_name" to "signup",
                    "button_location" to "hero"
                )
            )
        }
    }
}

The SDK is thread-safe, so you can call track from any thread without additional synchronization. This is particularly useful when tracking events from background operations or coroutines.

If you want to attach properties to every event automatically, use setGlobalProperties. This is helpful for including app version, build number, or environment information.

op.setGlobalProperties(
    mapOf(
        "app_version" to BuildConfig.VERSION_NAME,
        "build_number" to BuildConfig.VERSION_CODE.toString(),
        "platform" to "Android"
    )
)

Identify users

When a user logs in or you have information about who they are, call identify to associate their profile with tracked events. This enables user-level analytics and cohort analysis in your dashboard.

op.identify(
    user.id,
    mapOf(
        "firstName" to user.firstName,
        "lastName" to user.lastName,
        "email" to user.email,
        "plan" to user.plan
    )
)

When a user logs out, clear their data so subsequent events aren't attributed to them.

fun logout() {
    op.clear()
}

You can also increment numeric properties on user profiles. This is useful for tracking things like login counts or credits without needing to know the current value.

op.increment(user.id, "login_count", 1)

Track screen views

Screen view tracking helps you understand navigation patterns and which parts of your app get the most attention. The simplest approach is to create a base activity that tracks screen views automatically.

import androidx.appcompat.app.AppCompatActivity
import dev.openpanel.OpenPanel

abstract class BaseActivity : AppCompatActivity() {
    protected lateinit var op: OpenPanel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        op = OpenPanel.getInstance(this)
    }
    
    override fun onResume() {
        super.onResume()
        op.track(
            "screen_view",
            mapOf("screen_name" to this::class.simpleName ?: "Unknown")
        )
    }
}

For Jetpack Compose, use a LaunchedEffect to track when a composable screen appears.

import androidx.compose.runtime.LaunchedEffect
import dev.openpanel.OpenPanel

@Composable
fun MainScreen(op: OpenPanel) {
    LaunchedEffect(Unit) {
        op.track(
            "screen_view",
            mapOf("screen_name" to "MainScreen")
        )
    }
    
    // Your composable content
}

If you want the SDK to automatically track app lifecycle events like app_opened and app_closed, enable automatic tracking during initialization.

OpenPanel.create(
    context,
    OpenPanel.Options(
        clientId = "YOUR_CLIENT_ID",
        clientSecret = "YOUR_CLIENT_SECRET",
        automaticTracking = true
    )
)

Verify your setup

Run your Android app in an emulator or on a physical device and interact with a few screens and buttons. Open your OpenPanel dashboard and check the real-time view to see events arriving.

If events aren't appearing, check Logcat for error messages from the SDK. The most common issues are incorrect credentials or missing the clientSecret parameter. You can also use Android Studio's Network Profiler to verify that requests are being sent to OpenPanel's servers.

Next steps

The full Kotlin SDK reference covers additional options like event filtering and verbose logging. If you're building for multiple platforms, the React Native guide shows how to share analytics code across iOS and Android.

Loved by builders everywhere

From indie hackers to global teams, OpenPanel helps people understand their users effortlessly.

  • Steven Tey
    Steven Tey
    @steventey

    Open-source Mixpanel alternative just dropped → http://git.new/openpanel

    It combines the power of Mixpanel + the ease of use of @PlausibleHQ into a fully open-source product.

    Built by @CarlLindesvard and it’s already tracking 750K+ events 🤩

  • Pontus Abrahamsson - oss/acc
    Pontus Abrahamsson - oss/acc
    @pontusab

    Thanks, OpenPanel is a beast, love it!

  • Piotr Kulpinski
    Piotr Kulpinski
    @piotrkulpinski

    The Overview tab in OpenPanel is great. It has everything I need from my analytics: the stats, the graph, traffic sources, locations, devices, etc.

    The UI is beautiful ✨ Clean, modern look, very pleasing to the eye.

  • greg hodson 🍜
    greg hodson 🍜
    @h0dson

    i second this, openpanel is killing it

  • Jacob 🍀 Build in Public
    Jacob 🍀 Build in Public
    @javayhuwx

    🤯 wow, it's amazing! Just integrate @OpenPanelDev into http://indiehackers.site last night, and now I can see visitors coming from all round the world.

    OpenPanel has a more beautiful UI and much more powerful features when compared to Umami.

    #buildinpublic #indiehackers

  • Lee
    Lee
    @DutchEngIishman

    Day two of marketing.

    I like this upward trend..

    P.S. website went live on Sunday

    P.P.S. Openpanel by @CarlLindesvard is awesome.

Ready to understand your users better?
Start tracking in minutes

Join thousands of companies using OpenPanel. Free 30-day trial, no credit card required. Self-host for free or use our cloud.

Get started now