Respectlytics Respect lytics
Menu
Kotlin (Android) Paywall view Privacy-first

How to track paywall views in Kotlin (Android) without personal data

Paywall view is the top of the monetization funnel — and the place teams over-instrument with placement metadata, experiment assignment IDs, and per-user variant tracking. Respectlytics helps developers avoid collecting personal data in the first place: in Kotlin (Android), paywall view is one named event, with no payload. If you A/B-test placements or copy variants, encode the variant into the event name. Below: the Kotlin (Android) pattern, the conversion-rate math you can still do, and the metadata trade-offs.

Fire the call when the paywall surface is actually visible to the user — not on push, not on configure. SwiftUI/Compose/RN/Flutter visibility callbacks are the right hook. Don't pass the variant ID, the placement, or the offer config as metadata.

Install the Kotlin (Android) SDK

kotlin Respectlytics
// build.gradle.kts (app module)
dependencies {
    implementation("com.respectlytics:respectlytics-kotlin:3.0.0")
}

Pure Kotlin coroutines implementation. No Java dependencies, no Google Play Services dependencies. ~300KB DEX overhead — compare to roughly 3.8MB for Firebase Analytics (a measurable cold-start improvement on lower-end devices).

Initialize Respectlytics in Kotlin (Android)

kotlin Respectlytics
import com.respectlytics.android.Respectlytics

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Respectlytics.configure(this, appKey = "<YOUR_APP_KEY>")
    }
}

Initialize once in Application.onCreate. No additional permissions in the manifest — INTERNET is sufficient. The SDK does not request AD_ID, does not query AdvertisingIdClient, and does not declare ACCESS_NETWORK_STATE.

Track the event in Kotlin (Android)

kotlin Respectlytics
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import com.respectlytics.android.Respectlytics

@Composable
fun PaywallScreen() {
    LaunchedEffect(Unit) {
        // Fires once when the composable enters the composition.
        Respectlytics.track("paywall_view")
    }
    // ... paywall composable content ...
}

For Activity/Fragment-based UIs, fire in onResume() instead of onCreate() — create fires before the user can see anything.

Privacy & implementation notes

Fire the event on actual visibility, not on data fetch. SwiftUI's .onAppear, Compose's LaunchedEffect(Unit), RN's useFocusEffect, and Flutter's AfterFirstLayout mixin are the canonical hooks. Tracking on configure inflates the rate with paywalls the user never saw.

Experiment IDs are tempting because they look harmless — they're really not. A stable experiment ID across thousands of sessions becomes a per-user fingerprint via the variant assignment pattern. Encode the variant in the event name; discard the assignment ID.

Many teams discover the com.google.android.gms.permission.AD_ID permission in their merged manifest only after Google Play flags them — usually because a transitive dependency dragged it in. Respectlytics's Kotlin SDK has no Google Play Services dependency at all, so it cannot contribute to that merge.

The SDK is implemented as pure Kotlin coroutines with no Java sources, no RxJava, and no platform channels. Events are queued in a Channel<Event> buffered to a small ring (RAM-only), drained by a coroutine that flushes every 30 seconds or on backgrounding. There is no SharedPreferences usage.

How this compares to other analytics SDKs

Paywall view eventFirebase AnalyticsMixpanelRespectlytics
Per-user identityapp_instance_iddistinct_idNever
Variant / experiment ID as parameterRecommendedRecommendedUse distinct event_name
Placement (home, settings, …) as parameterRecommendedRecommendedUse distinct event_name
Computed metric: paywall_view → paywall_purchase ratePer-userPer-userSession-grouped
Bot / accidental view filteringHeuristic per userHeuristic per userCountry + session aggregate

Frequently asked questions

How do we measure paywall conversion rate without joining view → purchase per user?

Per-session. A session that emits both paywall_view and paywall_purchase is a converting session. The ratio across all sessions is your conversion rate. The noise from sessions where the user views the paywall on day 1 and converts on day 3 is small at scale — and your billing system already has the longitudinal truth.

Can we A/B-test paywall variants?

Yes. Emit paywall_view_a, paywall_view_b, etc., and pair with paywall_purchase_a, paywall_purchase_b. Per-variant conversion rate falls out of session-grouped event counts.

What about tracking which placement the paywall was shown from?

Distinct event names per placement: paywall_view_home, paywall_view_settings, paywall_view_post_onboarding. Keep the taxonomy short — under 8 placements is comfortable; past that, bucket the long tail.

Should we track the offered price or product set?

No. Pricing changes belong in your release notes and your billing system, not in your analytics pipeline. Mixing them in produces stale data the moment you change a price.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.