Screen-View Tracking (Jetpack Compose)

Automatically track screen views whenever the visible destination changes in a Jetpack Compose Navigation graph.

Overview

Sees360 can automatically emit a system analytics event whenever the visible screen changes in a Jetpack Compose Navigation graph.

  • Event name: sees_screen_view (predefined/system)
  • Primary param: screen_name — a stable screen name you define (see below)

The API lowercases all payload keys and values before persisting/exporting. Treat screen_name as a lowercase key (e.g., settings, home).

Requirements

  • Jetpack Compose + Navigation Compose
  • SDK initialized: Sees360.initialize(context, apiKey, identifier)
  • (Optional) Usage Stats permission if you use usage-stats features. Screen-view events do not require it.

Quick start

  1. Initialize the SDK (after your permission flow, if any).
  2. Add TrackScreenViews(navController) { destination -> screenKey } alongside your NavHost.
  3. Return stable, lowercase keys for each destination.
val nav = rememberNavController()

// Automatic screen-view tracking
TrackScreenViews(nav) { dest ->
    when (dest.route) {
        "home"                 -> "home"
        "details"              -> "details"
        "settings"             -> "settings"
        "profile/{userId}"     -> "profile"   // strip args -> stable key
        else                   -> "unknown"
    }
}

NavHost(navController = nav, startDestination = "home") {
    composable("home")     { HomeScreen(onGoDetails = { nav.navigate("details") },
                                        onGoSettings = { nav.navigate("settings") }) }
    composable("details")  { DetailsScreen(onBack = { nav.popBackStack() }) }
    composable("settings") { SettingsScreen(onBack = { nav.popBackStack() }) }
}

Each destination change emits sees_screen_view with screen_name set to your chosen screen name. Because the backend downcases payload values, “Home” would be stored as “home” — emitting lowercase from the client keeps local logs consistent with stored data.

Initialization & lifecycle

Initialize once permission exists; if a user grants permission in system settings, auto-initialize on return.

private var sdkInitialized = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ensureInitialized()
    setContent { /* NavHost + TrackScreenViews(...) */ }
}

override fun onResume() {
    super.onResume()
    if (!sdkInitialized) ensureInitialized()
}

private fun ensureInitialized() {
    val identifier = runBlocking { dataStore.data.first()[IDENTIFIER_KEY] ?: generateAndStoreIdentifier() }
    if (checkUsageStatsPermission(applicationContext)) {
        Sees360.initialize(applicationContext, BuildConfig.API_KEY, identifier)
        sdkInitialized = true
    } else {
        startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS))
        sdkInitialized = false
    }
}

Best practices

  • Stable keys only. No IDs or ephemeral UI state in screen_name (e.g., use profile, not profile:42).
  • One tracker per controller. If you have multiple NavControllers (tabs, nested graphs), attach a TrackScreenViews per controller.
  • Filter utility routes. To skip routes (dialogs/sheets), return "" or map them to a neutral key if your SDK ignores empty values.
  • Cross-platform alignment. Use the same keys on Android/iOS/Web for consistent dashboards.

Multiple graphs / tabs

TrackScreenViews(mainNav) {
    when (it.route) { "feed" -> "feed" else -> "main:${it.route}".lowercase() }
}

TrackScreenViews(settingsNav) {
    when (it.route) { "settings" -> "settings" else -> "settings:${it.route}".lowercase() }
}

Troubleshooting

  • No events firing: Ensure TrackScreenViews observes the same NavController used by NavHost.
  • Duplicate events: Only one tracker per controller.
  • Unexpected names: Routes with arguments must be matched by their pattern (e.g., "profile/{userId}"), not a concrete URI.

Event reference

  • Name: sees_screen_view
  • Payload (lowercased by backend):
    • screen_name: String — canonical screen key (lowercase)
{
  "event_name": "sees_screen_view",
  "payload": { "screen_name": "settings" }
}

Privacy & security

  • Avoid logging sensitive data (API keys, identifiers).
  • If your app supports analytics opt-out, render TrackScreenViews conditionally.

Do not include PII in screen_name.


This site uses Just the Docs, a documentation theme for Jekyll.