Wire each callback path to its own event_name: granted, denied, provisional, deferred. The platform permission API delivers the result asynchronously — fire on the result, not on the request.
▸Install the Kotlin (Android) SDK
// 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)
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)
import android.Manifest
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.content.ContextCompat
import com.respectlytics.android.Respectlytics
fun reportPermissionState(context: Context) {
val nm = ContextCompat.getSystemService(context, NotificationManager::class.java)!!
val isGranted = if (Build.VERSION.SDK_INT >= 33) {
ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) ==
android.content.pm.PackageManager.PERMISSION_GRANTED
} else nm.areNotificationsEnabled()
Respectlytics.track(if (isGranted) "push_optin" else "push_decline")
}
Android 13+ requires POST_NOTIFICATIONS; pre-13 reads notification-channel state via areNotificationsEnabled(). Both are checked here.
✦Privacy & implementation notes
Notification permission state is asymmetric: granting and revoking go through different OS pathways. Granting fires through your prompt callback; revoking happens silently in Settings, with no event delivered to your app. Detect revocation lazily on next foreground if you need it.
If you prompt at multiple points in the funnel (onboarding, post-first-session, after key feature), use distinct event names per timing — push_prompt_at_onboarding, push_prompt_post_session. Conversion-rate-by-timing falls out of session-grouped event counts.
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
| Notification permission event | Firebase Analytics | Mixpanel | Respectlytics |
|---|---|---|---|
| Per-user permission state | Yes (user property) | Yes (profile) | Out of scope |
| Push token / FCM ID stored | Yes | Yes | Never |
| Permission outcome states distinguishable | Manual (params) | Manual (params) | Distinct event_name per outcome |
| Time-to-grant after first prompt | Per-user | Per-user | Session-scoped |
❓Frequently asked questions
Should we track when the user revokes permission later?
Hard to detect reliably from the app. The OS doesn't deliver an explicit revocation event — you only learn at the next foreground when getNotificationSettings() returns denied. If you do detect it, fire push_revoked_detected (with no metadata) and use it for rate analysis only.
What's the right event for re-prompting after a deferred decision?
If you prompt twice, fire distinct events for each prompt: push_prompt_v1, push_prompt_v2. Apple and Google both have anti-spam policies — a second prompt is allowed only after meaningful product context, and you should instrument that decision point.
How does this differ from `push-opt-in`?
push-opt-in is the narrow event that fires on grant. notification-permission is the broader category that includes all permission outcomes — granted, denied, provisional, deferred, revoked. Use both, with non-overlapping event names per outcome.
What about silent / background-only notification capability?
On iOS, notification permission is independent from background-fetch capability. On Android 13+, POST_NOTIFICATIONS is required for visible notifications regardless of background fetch. If you care about background-only delivery, fire a separate push_background_only event when relevant.