Android SDK
Kixo Android SDK podporuje Kotlin 2.0+ i Java, vyžaduje minSdk 24 (Android 7.0) a je sestavené proti compileSdk 35. Vaše hostitelská aplikace si dál spravuje vlastní targetSdk. Jediné volání Kixo.configure ve vaší třídě Application.onCreate automaticky sleduje obrazovky, klepnutí, relace, pády aplikace i události životního cyklu. Sledování push notifikací vyžaduje níže popsaný FCM bridge. Automatické sledování síťových požadavků zatím aktuální verze pro Android neobsahuje. SDK podporuje také session replay, identitu a cíle.
Rychlý start
Tři soubory. Přidejte Maven repozitář, přidejte závislost a pak vložte dva řádky do podtřídy Application.
Požadavky na build: compileSdk 35, minSdk 24, Kotlin 2.0+ nebo Java a bytecode pro Java 17.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://raw.githubusercontent.com/kixoio/kixo-android-sdk/main/repo")
}
}
}Poznámka
Tím je integrace analytiky hotová. Běžné automatické trackery jsou ve výchozím stavu zapnuté; push ale stále vyžaduje níže popsaný FCM bridge. Jednotlivé volby přepisujte přes KixoConfiguration.Builder(...) jen když je to potřeba.
Přidání do aplikace
Repozitář Maven pro Kixo běží na GitHub Pages. Přidejte ho vedle google() a mavenCentral() do settings.gradle.kts:
// settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://raw.githubusercontent.com/kixoio/kixo-android-sdk/main/repo")
}
}
}Potom deklarujte závislost v modulu aplikace:
// app/build.gradle.kts
dependencies {
implementation("io.kixo:kixo-android-sdk:0.1.20")
}Tip
android.permission.INTERNET a android.permission.ACCESS_NETWORK_STATE už jsou součástí manifestu SDK. Oprávnění k notifikacím zůstávají plně na vaší aplikaci a deklarujete je až ve chvíli, kdy zapnete push funkce.
Vícemodulové projekty
Konfigurace implementation v Gradle je není tranzitivní: když v knihovním modulu (např. :core_domain) deklarujete implementation("io.kixo:kixo-android-sdk:0.1.20"), Kixo se tím NEzpřístupní pro :app ani pro žádného dalšího konzumenta. Fungují dva přístupy — vyberte si jeden.
Varianta A — každý modul, který volá Kixo, ho deklaruje sám (doporučeno). Udržuje classpath jednotlivých modulů co nejmenší a omezuje řetězení rebuildů. Použijte version catalog (libs.kixo.sdk), abyste verzi měnili jen na jednom místě.
// :core_domain/build.gradle.kts
dependencies {
implementation("io.kixo:kixo-android-sdk:0.1.20") // local use only
}
// :app/build.gradle.kts
dependencies {
implementation(project(":core_domain"))
implementation("io.kixo:kixo-android-sdk:0.1.20") // declared again — fine
}Varianta B — reexport přes api(...). Stačí jediná deklarace, ale do veřejného ABI knihovního modulu se tím dostanou typy Kixo — každá změna verze pak vyvolá rebuild všech navazujících modulů. Použijte to jen tehdy, když knihovna používá typy Kixo i ve svých veřejných signaturách, například vrací KixoDiagnostics.
// :core_domain/build.gradle.kts
dependencies {
api("io.kixo:kixo-android-sdk:0.1.20") // re-exposed
}
// :app/build.gradle.kts
dependencies {
implementation(project(":core_domain")) // gets Kixo for free
}Upozornění
Jestli při kompilaci v modulu vidíte Unresolved reference: Kixo, chybí mu vlastní přímá závislost na SDK — přidejte výše uvedený řádek implementation, nebo použijte variantu B.
Inicializace
Kixo nastavte ve vlastní podtřídě Application — onCreate se spustí dřív než jakákoli activity, takže se každé zobrazení obrazovky, klepnutí i událost životního cyklu zachytí už od prvního snímku. Do manifestu pak zaregistrujte Application pomocí android:name=".MyApp".
import android.app.Application
import io.kixo.sdk.Kixo
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Kixo.configure(
context = this,
projectId = "kx_proj_YOUR_PROJECT_ID",
apiKey = "kx_key_YOUR_API_KEY",
)
}
}Pokud potřebujete jemnější nastavení — například přepínače automatického sledování, interval flushování, vzorkování replaye nebo vlastní API host — vytvořte KixoConfiguration explicitně:
import io.kixo.sdk.Kixo
import io.kixo.sdk.KixoConfiguration
val config = KixoConfiguration.Builder(
projectId = "kx_proj_YOUR_PROJECT_ID",
apiKey = "kx_key_YOUR_API_KEY",
)
.autoTrackScreens(true)
.autoTrackTaps(true)
.autoTrackNetwork(false) // reserved; no-op in the current Android release
.autoTrackCrashes(true)
.autoTrackSessions(true)
.autoTrackPush(true)
.flushIntervalMillis(30_000)
.flushAt(20)
.maxBufferSize(200)
.build(applicationContext)
Kixo.configure(this, config)Poznámka
Idempotentní. Druhé volání configure ve stejném procesu se jen zaloguje jako WARN a nic neprovede — SDK ponechá původní konfiguraci. Události, které váš auth singleton zařadí do fronty ještě předtím, než v ještě předtím, než doběhne configure, se uloží do bufferu (max. 50) a po inicializaci SDK se odehrají, takže Kixo.identify(...) můžete volat i z globálního místa ještě před dokončením Application.onCreate.
Zaznamenávání událostí
Většinu instrumentace pokrývají tři základní primitiva: track pro události, markGoal pro konverzní signály a addBreadcrumb pro kontext mimo události.
import io.kixo.sdk.Kixo
Kixo.track("video_played", mapOf(
"video_id" to "vid_42",
"duration_ms" to 18_500,
"autoplay" to false,
))
// markGoal(name, value?, currency?, properties?) — pass extra context
// through the named 'properties' argument (a Map can't be the 2nd
// positional arg; that slot is the Double 'value').
Kixo.markGoal("activated", properties = mapOf(
"step" to "onboarding_completed",
))
// Revenue goals use the typed value + currency parameters:
Kixo.markGoal("purchase_completed", value = 49.99, currency = "USD")
Kixo.addBreadcrumb(
message = "user toggled dark mode",
category = "ui",
level = "info",
)Tip
Cíle mají úrovně. Označené cíle se propisují do aktivačních funnelů v Kixo i do denní cron úlohy pro detekci změn — pokud objem některého cíle mezitýdně klesne o 70 %, v dashboardu se u něj zobrazí štítek Čeká na kontrolu. markGoal používejte jen pro několik klíčových okamžiků, track pro všechno ostatní.
Standardní události
Lehká nadstavba nad Kixo.track pro události, které Kixo rozpoznává podle názvu — tedy přesné řetězcové klíče, na které se shoduje backendový detektor standardních událostí. Přináší kontrolu tvaru vlastností při kompilaci a jedno místo, kde se drží názvy.
import io.kixo.sdk.Kixo
import io.kixo.sdk.SubscriptionInterval
Kixo.trackPurchase(
amount = 49.99,
currency = "USD",
productId = "pro_yearly",
)
Kixo.trackSubscriptionStart(
plan = "pro",
amount = 9.99,
currency = "USD",
interval = SubscriptionInterval.MONTH,
)
Kixo.trackSignup(method = "google")
Kixo.trackTrialStart(plan = "pro", days = 14)
Kixo.trackCancel(plan = "pro", reason = "too_expensive")
Kixo.trackUpgrade(fromPlan = "free", toPlan = "pro")
Kixo.trackActivation(event = "first_post_published")
Kixo.trackShare(channel = "twitter", contentId = "post_123")
Kixo.trackInvite(channel = "email", recipientCount = 5)Identifikace uživatelů
Naváže další události na stabilní ID uživatele a sadu traitů. Propojení anonymního a známého uživatele probíhá v Kixo — události zachycené před identify se zpětně přiřadí stejnému uživateli.
import io.kixo.sdk.Kixo
// Reserved standard property keys carry a $-prefix (Mixpanel
// convention) so they namespace away from your own custom traits
// and promote to the dashboard's profile columns. See
// io.kixo.sdk.StandardProperty for the typed catalogue, or the
// "Standard property catalog" section below for the full 37-key list.
Kixo.identify("user_123", mapOf(
"$email" to "jane@example.com", // identity
"$name" to "Jane Doe", // identity
"$plan" to "pro", // subscription pack
"$lifetime_orders" to 12, // e-commerce pack
"signup_source" to "twitter_ad", // custom trait
))
// Logout: clear identity, super-properties, and the persisted queue.
Kixo.reset()⚠️ Pozor na znak dolaru v Kotlinu. Standardní klíče identity mají prefix $ ($email, $name, $first_name) — a v Kotlin literálu musíte znak dolaru zapisujete jako "\$email". Když napíšete "$email", provede se interpolace proměnné email, takže hodnota tiše skončí jako trait vlastní a nikdy nevyplní sloupce Audience email / name. Nejjednodušší oprava je použít typovaný overload (SDK 0.1.13+), kde se to stát nemůže: Kixo.setUserProperty(StandardProperty.EMAIL, email).
Označte uživatele pro segmentaci
Pomocí setUserProperty s hodnotou boolean přidáte uživateli jednoduchý příznak ano/ne. Zůstane zachovaný i po dalším spuštění aplikace a bez dalšího nastavování ho můžete použít v segmentech, e-mailových kampaních i dotazech v chatu — stačí volání SDK.
// Tag a user as subscribed — segments + campaigns can target this
Kixo.setUserProperty("subscribe", true)
// VIP membership
Kixo.setUserProperty("vip", true)
// String + numeric values work too
Kixo.setUserProperty("plan_tier", "enterprise")
Kixo.setUserProperty("lifetime_orders", 42)
// Bulk-set
Kixo.setUserProperties(mapOf(
"subscribe" to true,
"plan_tier" to "enterprise",
))Vlastnosti se přes SharedPreferences ukládají i mezi spuštěními a automaticky se připojují ke každé odchozí události. V chatu pak můžete psát třeba "odeslat uvítací e-mail uživatelům, kde subscribe je true" — Kixo za vás sestaví segment a připraví návrh šablony. Mažou se při Kixo.reset().
Katalog standardních vlastností
Vyhrazené klíče vlastností mají prefix $, aby byly oddělené od vašich vlastních atributů. Katalog Kixo pokrývá 37 klíčů ve 3 univerzálních sadách (identita, geo, životní cyklus) a 5 oborových sadách pro B2B (předplatné, e-commerce, média, marketplace, věrnost). Nastavte jen ty, které dávají smysl pro váš produkt — dashboard se přizpůsobí a zobrazí jen sady, které skutečně používáte.
Identita
Vždy relevantní. Určuje sloupce v záhlaví profilu.
| Klíč | Typ | Popis |
|---|---|---|
$email | řetězec | Primární e-mail, často používaný jako merge key pro spojování identit. |
$phone | řetězec | Telefonní číslo ve formátu E.164. |
$name | řetězec | Celé zobrazované jméno. |
$first_name | řetězec | Jméno. |
$last_name | řetězec | Příjmení. |
$avatar_url | řetězec | Plná URL adresa avataru uživatele. |
Geo
Geografický kontext.
| Klíč | Typ | Popis |
|---|---|---|
$country | řetězec | Kód země podle ISO 3166. |
$city | řetězec | Název města. |
$region | řetězec | Stát nebo provincie. |
$timezone | řetězec | IANA zóna, například America/Los_Angeles. |
$language | řetězec | IETF tag, například en nebo ru-RU. |
$locale | řetězec | Úplný identifikátor locale. |
Životní cyklus
Kdy jsme ho zaznamenali.
| Klíč | Typ | Popis |
|---|---|---|
$created | ISO8601 | Čas registrace nebo vytvoření účtu. |
$last_seen | ISO8601 | Čas poslední interakce. |
Předplatné
Nastavte, pokud má váš produkt tarify.
| Klíč | Typ | Popis |
|---|---|---|
$plan | řetězec | Slug tarifu — free, pro, enterprise. |
$subscription_status | řetězec | active / trial / cancelled / past_due. |
$trial_ends | ISO8601 | Kdy končí aktuální zkušební období. |
$mrr | číslo | Měsíční opakované tržby v měně účtu. |
$subscription_started | ISO8601 | Kdy začalo aktuální předplatné. |
E-commerce
Nastavte, pokud prodáváte produkty.
| Klíč | Typ | Popis |
|---|---|---|
$lifetime_orders | číslo | Počet dokončených objednávek. |
$lifetime_revenue | číslo | Celková útrata. |
$aov | číslo | Průměrná hodnota objednávky. |
$last_purchase | ISO8601 | Poslední úspěšný nákup. |
$first_purchase | ISO8601 | První úspěšný nákup. |
$cart_abandoned_count | číslo | Celkový počet opuštění košíku. |
Média
Nastavte, pokud publikujete obsah.
| Klíč | Typ | Popis |
|---|---|---|
$content_tier | řetězec | free / premium / paid. |
$subscribed_categories | Řetězec CSV nebo pole | Kategorie, které uživatel sleduje. |
$watch_time_total | číslo | Celková doba sledování v sekundách. |
$last_played | ISO8601 | Čas posledního spuštění přehrávání. |
Marketplace
Nastavte, pokud provozujete dvoustrannou platformu.
| Klíč | Typ | Popis |
|---|---|---|
$seller_tier | řetězec | Slug tarifu na straně prodejce. |
$buyer_tier | řetězec | Slug tarifu na straně kupujícího. |
$listings_count | číslo | Aktivní nabídky, které uživatel vlastní. |
$reviews_count | číslo | Recenze, které uživatel obdržel. |
$verified | boolean | Stav KYC. |
Věrnost
Nastavte pro programy zapojení a odměn.
| Klíč | Typ | Popis |
|---|---|---|
$loyalty_points | číslo | Aktuální zůstatek bodů k uplatnění. |
$vip_level | řetězec | Slug VIP úrovně. |
$referral_count | číslo | Úspěšná doporučení připsaná tomuto uživateli. |
Tip
Nevidíte svůj případ? Pro vlastní atributy používejte klíče bez prefixu. V dashboardu se zobrazí v panelu Custom Traits, aniž by zaplnily sloupce profilu. Pět oborových balíčků výše je jen praktický odhad nejběžnějších modelů v B2B — terminologie specifická pro zákazníka (např. shipping_plan) zůstává bez prefixu.
Super-properties
Páry klíč/hodnota pro relaci, které se automaticky připojují ke každé odchozí události. Na rozdíl od traitů identify, které popisují identitu, super-properties vyjadřují kontext relace — například aktivní variantu A/B testu, build flavor nebo zapnuté feature flagy. Přetrvají i po dalším spuštění a smažou se při reset(). Při kolizi mají vždy přednost hodnoty properties zadané přímo u track.
import io.kixo.sdk.Kixo
Kixo.setSuperProperty("build_flavor", "beta")
Kixo.setSuperProperties(mapOf(
"ab_variant" to "B",
"referrer_campaign" to "autumn-launch",
))
// Sugar for A/B tracking — stored as 'experiment_<id>'.
Kixo.setExperimentVariant("checkout_v2", "variant_a")
Kixo.unsetSuperProperty("build_flavor")
Kixo.clearSuperProperties()Push notifikace
K dispozici jsou dvě integrační cesty. Variantu A zvolte, pokud používáte FCM a chcete nejkratší funkční nastavení. Variantu B zvolte, pokud už máte vlastní FirebaseMessagingService, kterou nemůžete přeuspořádat, nebo chcete mít přesnou kontrolu nad tím, která doručení z FCM Kixo uvidí.
Možnost A — rozšiřte KixoFirebaseMessagingService (automatické sledování)
Vytvořte podtřídu KixoFirebaseMessagingService a ve své implementaci zavolejte super.onMessageReceived(...) — Kixo pak automaticky odešle push_received (viditelný payload) nebo push_silent (jen data). Základní třída také řeší registraci onNewToken, pokud ji sami nepřepíšete. Registrace AndroidManifest.xml zůstává stejná jako u běžné služby FCM.
import com.google.firebase.messaging.RemoteMessage
import io.kixo.sdk.KixoFirebaseMessagingService
class MyMessagingService : KixoFirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage) // Kixo auto-tracks push_received
// … your own routing / notification display
}
}Poznámka
Kixo tuto volitelnou třídu kompiluje proti Firebase Messaging, ale nepřidává Firebase do vaší aplikace tranzitivně. SDK deklaruje Firebase jako compileOnly; aplikace, která tuto variantu použije, proto musí sama záviset na firebase-messaging, stejně jako u libovolného FCM receiveru.
Možnost B — volejte ručně API z vlastní služby FCM
Zaregistrujte svůj token FCM do Kixo přes FirebaseMessagingService.onNewToken a potom každé doručení zapisujte výslovně. Tuto cestu zvolte, pokud má Kixo vidět jen část doručení z FCM. Doručování na Android momentálně podporuje jen FCM.
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import io.kixo.sdk.Kixo
import io.kixo.sdk.PushProvider
class MyMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
Kixo.setPushToken(token, PushProvider.FCM)
}
override fun onMessageReceived(message: RemoteMessage) {
// Convert the FCM payload to a Map<String, Any?> and log it —
// Kixo correlates this with the open / dismiss it sees later.
Kixo.logPushReceived(message.data.toMap(), appState = "background")
}
}Android neposkytuje jednotný lifecycle hook pro otevření notifikace, její zavření ani tlačítka akcí. Tyto signály proto předejte z notification intentů nebo receiverů, které vaše aplikace vytváří:
import io.kixo.sdk.Kixo
Kixo.logPushOpened(payload = pushPayload) // open
Kixo.logPushOpened(payload = pushPayload, actionId = "reply") // action-button tap
Kixo.logPushDismissed(payload = pushPayload) // swipe-awayPřehrání relace
Přehrajte si skutečnou vizuální rekonstrukci toho, co uživatel viděl. Při každém záznamu SDK zakóduje komprimovaný snímek obrazovky (obrázek JPEG) spolu se strukturálním snímkem hierarchie zobrazení a obojí odešle — přehrávač v dashboardu pak vykreslí přehrání s přesností na pixely vedle časové osy interakcí. Session replay pro projekt nastavíte v Přehled → Nastavení → Přehrání relace. SDK tuto projektovou politiku automaticky načítá a průběžně obnovuje, včetně maskování, režimů záznamu a povolení odesílání přes mobilní síť.
import io.kixo.sdk.Kixo
import io.kixo.sdk.KixoConfiguration
val config = KixoConfiguration.Builder(
projectId = "kx_proj_YOUR_PROJECT_ID",
apiKey = "kx_key_YOUR_API_KEY",
)
.build(applicationContext)
Kixo.configure(this, config)Když je odesílání přes mobilní síť vypnuté, replay ve frontě čeká na povolené připojení.
Tip
Maskování před odesláním. Kixo pracuje s pixely, takže maskování probíhá ještě předtím, než, ještě než cokoli opustí zařízení. Pole pro heslo a e-mail rozpozná a začerní automaticky, text ve strukturálních snímcích prochází filtrem PII a každé view označené setKixoMask(true) se v obrazu vykreslí jako neprůhledný obdélník ještě předtím, než, než se zakóduje JPEG — jeho pixely tedy zařízení nikdy neopustí. Obrazovky v Jetpack Compose jsou ve výchozím stavu maskované celé; pokud chcete zahrnout obrazovku, kterou jste zkontrolovali, zavolejte setKixoMask(false) na nejvyšším ComposeView. Operátoři pak v dashboardu procházejí přehrávač relace vedle časové osy událostí.
Sběr dat
SDK zachytává data povolená v projektu i události a vlastnosti, které odesílá vaše aplikace.
Ladění
Kixo.diagnostics() vrací snapshot stavu SDK jen pro čtení — hodí se do skryté debug obrazovky i do smoke testu. Bez debuggeru rychle ukáže, proč události neodcházejí.
import io.kixo.sdk.Kixo
val diag = Kixo.diagnostics()
Log.d("Kixo", "queued=${diag.queue.bufferedEventCount}")
Log.d("Kixo", "paused=${diag.paused}") // collection paused state
Log.d("Kixo", "lifecycleState=${diag.lifecycleState}") // SDK lifecycle stateVynuťte flush z testovacího harnessu — běh se zablokuje až na timeoutMs kvůli jednomu síťovému round tripu:
import io.kixo.sdk.Kixo
// Async fire-and-forget — returns immediately.
Kixo.flush()
// Blocking variant for instrumentation tests. Never call on the main thread.
val landed: Boolean = Kixo.flushBlocking(timeoutMs = 5_000L)
assertTrue(landed)Compose Navigation
Trasy Activity / Fragment automaticky vytvářejí okamžité události screen_view a zároveň strukturované záznamy screen_visit s metadaty o době zobrazení a průchodu aplikací. U Jetpack Compose Navigation volejte Kixo.screen z LaunchedEffect navázaného na route — SDK pak uvidí jednu událost pro každý cíl bez ohledu na počet rekompozic.
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import io.kixo.sdk.Kixo
@Composable
fun AppNavHost(nav: NavHostController) {
NavHost(navController = nav, startDestination = "home") {
composable("home") {
LaunchedEffect("home") { Kixo.screen("HomeScreen") }
HomeScreen()
}
composable("settings") {
LaunchedEffect("settings") { Kixo.screen("SettingsScreen") }
SettingsScreen()
}
}
}AI agenti pro vývoj
Veřejné rozhraní SDK je malé a navržené pro pohodlné doplňování v editoru — všechny metody jsou na singletonu Kixo, každý ukázkový Kotlin v tomto průvodci začíná import io.kixo.sdk.Kixo a v našem README je blok „AI agent quick reference“, který si nástroje jako Claude Code, Cursor a Codex můžou vložit přímo do kontextu. Pokud se agent zasekne, začněte tímto základním příkladem:
// Tell your AI coding agent:
// "Integrate the Kixo Android SDK using io.kixo:kixo-android-sdk
// from https://raw.githubusercontent.com/kixoio/kixo-android-sdk/main/repo.
// Call Kixo.configure(this, projectId, apiKey) in Application.onCreate.
// Then use Kixo.track / Kixo.identify / Kixo.markGoal as needed."Poznámka
Všechny části výše jsou psané s ohledem na tento způsob práce — importy jsou vždy explicitní, typy vždy pojmenované a singleton SDK se nikdy nealiasuje. Tuto stránku můžete předat agentovi a nechat ho pokračovat.