▸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.
✦Privacy & implementation notes
GDPR's Article 4(1) classifies IP addresses as personal data, with narrowing case law on transient-purpose processing. The ECJ's Patrick Breyer v. Bundesrepublik Deutschland (2016) and subsequent cases established that even "dynamic" IPs are personal data when the recipient has the means to identify the user. The transient-discard pattern minimises the data-retention surface but doesn't eliminate the legal classification — consult your legal team.
The country code stored in events is sufficient for the most common product breakdown — "how does this metric vary by market?". Going deeper (city, ZIP) almost always falls into either a marketing-ads use case (handled elsewhere) or a vanity dashboard that doesn't drive product decisions.
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
| Geolocation handling | Firebase Analytics | Mixpanel | Amplitude | Respectlytics |
|---|---|---|---|---|
| Stores IP address | Yes | Yes (90 days default) | Yes | No (discarded after lookup) |
| Stores precise lat/long | Optional | Optional | Optional | No |
| Stores city / region | Yes | Yes | Yes | No |
| Stores country code | Yes | Yes | Yes | Yes |
| Per-user location history | Yes | Yes | Yes | No |
| Reverse-DNS or VPN detection | Yes | Yes | Yes | No |
❓Frequently asked questions
Is the IP-address-then-discarded path still considered processing PII?
Most regulators (including the EU's EDPB) classify IP addresses as personal data even when transiently held for a strictly defined purpose. The transient-then-discarded pattern is generally accepted as the most minimised viable approach for country lookup. Consult your legal team for the exact framing in your jurisdiction; the standard disclaimer applies.
How accurate is the country lookup?
We use MaxMind GeoLite2's country database, refreshed monthly. Accuracy is ~99% for standard residential and mobile IP ranges; lower for VPNs, Tor, and corporate egresses. For country-level rollups in product analytics, the accuracy is sufficient.
Can we get city-level breakdowns for marketing?
Not from Respectlytics, by design. City-level geolocation is one of the more privacy-sensitive analytics fields and is not aligned with the ROA philosophy. If you genuinely need city-level breakdowns for paid ads campaigns, your ads platform provides them on its own (Google Ads, Meta Ads) — that lives in the ads attribution layer, not in product analytics.
What about regions like Hong Kong / Taiwan / Crimea — how are they assigned?
Respectlytics uses ISO 3166-1 alpha-2 country codes from MaxMind. Regions with politically contested status are coded by MaxMind's geographic convention, not by political alignment. If your audience needs a finer regional breakdown for a specific reason, the workaround is to fire distinct event_names per region of interest.