Android SDK
Kixo Android SDK podržava Kotlin 2.0+ i Javu, zahtijeva minSdk 24 (Android 7.0) i buildan je prema compileSdk 35. Vaša host aplikacija i dalje sama upravlja vlastitim targetSdk. Jedan poziv Kixo.configure u vašem Application.onCreate automatski prati ekrane, dodire, sesije, rušenja aplikacije i događaje životnog ciklusa. Za praćenje push obavijesti potreban je FCM most opisan ispod. Automatsko praćenje mrežnih zahtjeva trenutno nije dio Android izdanja. SDK podržava i session replay, identitet i ciljeve.
Brzi početak
Tri datoteke. Dodajte Maven repo, dodajte zavisnost, pa onda ubacite dvije linije u svoju podklasu Application.
Zahtjevi za build: compileSdk 35, minSdk 24, Kotlin 2.0+ ili Java, te Java 17 bytecode.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://raw.githubusercontent.com/kixoio/kixo-android-sdk/main/repo")
}
}
}Napomena
To je cijela integracija analitike. Standardni automatski trackeri uključeni su po zadanim postavkama; za push je i dalje potreban FCM most ispod. Pojedinačne oznake mijenjajte s KixoConfiguration.Builder(...) samo kada je potrebno.
Dodajte u aplikaciju
Kixo Maven repo hostuje se na GitHub Pages. Dodajte ga uz google() i mavenCentral() u 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")
}
}
}Zatim deklarirajte zavisnost u app modulu:
// app/build.gradle.kts
dependencies {
implementation("io.kixo:kixo-android-sdk:0.1.20")
}Savjet
android.permission.INTERNET i android.permission.ACCESS_NETWORK_STATE uključeni su u SDK manifest. Dozvolama za obavijesti i dalje upravlja vaša aplikacija i deklarirate ih kada uključite push funkcije.
Projekti s više modula
Gradle konfiguracija implementation je nije tranzitivno: deklarisanje implementation("io.kixo:kixo-android-sdk:0.1.20") u bibliotečkom modulu (npr. :core_domain) NE čini Kixo vidljivim za :app niti za bilo kojeg drugog potrošača. Postoje dva ispravna obrasca — izaberite jedan.
Obrazac A — svaki modul koji poziva Kixo i deklarira ga (preporučeno). Drži classpath svakog modula što manjim i izbjegava lančane ponovne izgradnje. Koristite version catalog (libs.kixo.sdk) da verziju mijenjate na jednom mjestu.
// :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
}Obrazac B — ponovni izvoz kroz api(...). Jedna deklaracija, ali javni ABI bibliotečkog modula sada uključuje Kixo tipove — svako povećanje verzije pokreće ponovnu izgradnju svih downstream modula. Koristite ovo samo kada biblioteka koristi Kixo tipove i u vlastitim javnim potpisima, npr. kada funkcija vraća 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
}Upozorenje
Ako pri kompilaciji u nekom modulu vidite Unresolved reference: Kixo, tom modulu nedostaje vlastita zavisnost od SDK-a — dodajte gornji implementation red ili koristite obrazac B.
Inicijalizacija
Konfigurirajte Kixo iz svoje podklase Application — onCreate se izvršava prije bilo koje aktivnosti, pa se svaki pregled ekrana, dodir i događaj životnog ciklusa bilježi od prvog frejma. Registrirajte Application u manifestu s 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",
)
}
}Za preciznija podešavanja (oznake za automatsko praćenje, ritam flushanja, uzorkovanje replaya, prilagođeni API host) eksplicitno napravite KixoConfiguration:
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)Napomena
Idempotentno. Drugi poziv configure iz istog procesa ne radi ništa i bilježi se kao WARN — SDK zadržava prvu konfiguraciju. Događaji koje vaš auth singleton stavi u red prije nego što prije configure stigne čuvaju se u međuspremniku (do 50) i šalju se kad se SDK poveže, pa Kixo.identify(...) možete pozvati iz globalnog opsega prije nego što Application.onCreate završi.
Pratite događaje
Tri osnove nose glavninu vaše instrumentacije: track za događaje, markGoal za signale konverzije i addBreadcrumb za kontekst koji nije događaj.
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",
)Savjet
Ciljevi imaju težinu. Označeni ciljevi ulaze u Kixo aktivacione funnele i dnevni cron za otkrivanje promjena — cilj čiji obim padne 70% u odnosu na prethodnu sedmicu pojavit će se u vašem dashboardu s oznakom Treba pregledati. Koristite markGoal za mali broj trenutaka koji su zaista bitni; track za sve ostalo.
Standardni događaji
Praktični sloj preko Kixo.track za događaje koje Kixo prepoznaje po nazivu — doslovne string ključeve koje backend detektor standardnih događaja prepoznaje. Dobijate provjeru oblika svojstava pri kompilaciji i jedno mjesto istine za imenovanje.
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)Identificirajte korisnike
Povežite naredne događaje sa stabilnim ID-em korisnika i skupom traitova. Spajanje anonimnog i poznatog korisnika radi se u Kixo — događaji zabilježeni prije identify naknadno se pripisuju istom korisniku.
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()⚠️ Kotlin zamka sa znakom dolara. Standardni ključevi identiteta imaju prefiks $ ($email, $name, $first_name) — a u Kotlin literalu znak dolara mora escapeovati kao "\$email". Ako napišete "$email", interpolirat ćete varijablu email, pa će vrijednost neprimjetno završiti kao trait prilagođeno i nikad neće popuniti kolone email / name u Audience. Najjednostavnije rješenje je tipizirani overload (SDK 0.1.13+), koji je praktično nemoguće pogriješiti: Kixo.setUserProperty(StandardProperty.EMAIL, email).
Označite korisnika za segmentaciju
Koristite setUserProperty s vrijednošću boolean da korisniku dodate jednostavnu da/ne oznaku. Oznaka ostaje sačuvana kroz pokretanja aplikacije i koristi se za segmente, email kampanje i upite u chatu — bez dodatnog podešavanja osim SDK poziva.
// 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",
))Svojstva se čuvaju putem SharedPreferences kroz ponovna pokretanja i automatski se dodaju svakom odlaznom događaju. U chatu recite nešto poput "pošalji email dobrodošlice korisnicima gdje je subscribe true" — Kixo će za vas napraviti segment i pripremiti nacrt predloška. Brišu se na Kixo.reset().
Katalog standardnih svojstava
Rezervisani ključevi svojstava nose prefiks $, kako bi bili odvojeni od vaših prilagođenih svojstava. Kixo katalog pokriva 37 ključeva u 3 univerzalna paketa (identity, geo, lifecycle) i 5 B2B vertikalnih paketa (subscription, e-commerce, media, marketplace, loyalty). Postavite samo ono što se odnosi na vaš proizvod — dashboard se prilagođava i prikazuje samo pakete koje popunite.
Identitet
Uvijek relevantno. Postavlja kolone zaglavlja profila.
| Ključ | Tip | Opis |
|---|---|---|
$email | string | Primarni email, često ključ za spajanje identiteta. |
$phone | string | E.164 broj telefona. |
$name | string | Puno prikazano ime. |
$first_name | string | Ime. |
$last_name | string | Prezime. |
$avatar_url | string | Puni URL slike avatara korisnika. |
Geo
Geografski kontekst.
| Ključ | Tip | Opis |
|---|---|---|
$country | string | ISO 3166 kod države. |
$city | string | Naziv grada. |
$region | string | Savezna država ili pokrajina. |
$timezone | string | IANA zona kao America/Los_Angeles. |
$language | string | IETF oznaka kao en ili ru-RU. |
$locale | string | Puni locale identifikator. |
Životni ciklus
Kada smo ih vidjeli.
| Ključ | Tip | Opis |
|---|---|---|
$created | ISO8601 | Vrijeme registracije ili kreiranja računa. |
$last_seen | ISO8601 | Vrijeme posljednje interakcije. |
Pretplata
Postavite ako vaš proizvod ima pakete.
| Ključ | Tip | Opis |
|---|---|---|
$plan | string | Slug nivoa — free, pro, enterprise. |
$subscription_status | string | active / trial / cancelled / past_due. |
$trial_ends | ISO8601 | Kada ističe trenutni probni period. |
$mrr | broj | Mjesečni ponavljajući prihod u valuti računa. |
$subscription_started | ISO8601 | Kada je počela trenutna pretplata. |
E-commerce
Postavite ako prodajete proizvode.
| Ključ | Tip | Opis |
|---|---|---|
$lifetime_orders | broj | Broj završenih narudžbi. |
$lifetime_revenue | broj | Ukupna potrošnja. |
$aov | broj | Prosječna vrijednost narudžbe. |
$last_purchase | ISO8601 | Posljednja uspješna kupovina. |
$first_purchase | ISO8601 | Prva uspješna kupovina. |
$cart_abandoned_count | broj | Ukupan broj napuštenih korpi. |
Mediji
Postavite ako objavljujete sadržaj.
| Ključ | Tip | Opis |
|---|---|---|
$content_tier | string | free / premium / paid. |
$subscribed_categories | CSV string ili niz | Kategorije koje korisnik prati. |
$watch_time_total | broj | Ukupno vrijeme gledanja u sekundama. |
$last_played | ISO8601 | Posljednji početak reprodukcije. |
Tržište
Postavite ako ste dvosmjerna platforma.
| Ključ | Tip | Opis |
|---|---|---|
$seller_tier | string | Slug nivoa na strani prodavača. |
$buyer_tier | string | Slug nivoa na strani kupca. |
$listings_count | broj | Aktivni oglasi u vlasništvu korisnika. |
$reviews_count | broj | Recenzije koje je korisnik primio. |
$verified | boolean | KYC status. |
Lojalnost
Postavite ako imate programe angažmana i nagrađivanja.
| Ključ | Tip | Opis |
|---|---|---|
$loyalty_points | broj | Trenutni raspoloživi saldo bodova. |
$vip_level | string | VIP slug nivoa. |
$referral_count | broj | Uspješne preporuke pripisane ovom korisniku. |
Savjet
Ne vidite svoj obrazac? Za prilagođene traitove koristite obične ključeve. Pojavit će se u panelu Custom Traits na dashboardu bez zagađivanja kolona profila. Pet vertikalnih paketa iznad predstavljaju promišljene pretpostavke za najčešće B2B obrasce — terminologija specifična za kupca, npr. shipping_plan, ostaje bez prefiksa.
Super-properties
Parovi ključ/vrijednost po sesiji koji se automatski dodaju svakom odlaznom događaju. Razlikuju se od traitova identify (koji opisuju identitet); super-properties opisuju kontekst sesije — aktivnu A/B varijantu, build flavor, uključene feature flagove. Ostaju sačuvani kroz ponovna pokretanja; brišu se na reset(). Ako dođe do kolizije, per-event properties na track uvijek imaju prednost.
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 obavijesti
Postoje dva puta integracije. Izaberite A ako koristite FCM i želite najkraće ispravno podešavanje; izaberite B ako već imate prilagođeni FirebaseMessagingService koji ne možete restrukturirati ili želite eksplicitnu kontrolu nad tim koje FCM isporuke Kixo vidi.
Opcija A — proširite KixoFirebaseMessagingService (automatsko praćenje)
Napravite podklasu KixoFirebaseMessagingService i iz svog overridea pozovite super.onMessageReceived(...) — Kixo automatski emituje push_received (vidljiv payload) ili push_silent (samo podaci). Bazna klasa obrađuje i registraciju onNewToken ako je ne overrideate. Registracija AndroidManifest.xml ostaje ista kao kod običnog FCM servisa.
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
}
}Napomena
Kixo ovu opcionalnu klasu kompilira prema Firebase Messagingu, ali Firebase ne dodaje tranzitivno u vašu aplikaciju. SDK deklarira Firebase kao compileOnly; aplikacija koja bira ovu opciju već mora zavisiti od firebase-messaging, kao i svaki FCM receiver.
Opcija B — pozovite ručni API iz vlastitog FCM servisa
Registrirajte svoj FCM token u Kixo putem FirebaseMessagingService.onNewToken, a zatim svaku isporuku bilježite eksplicitno. Ovaj pristup koristite kada želite da Kixo vidi samo dio FCM isporuka. Android isporuka trenutno podržava samo 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 ne nudi univerzalni lifecycle hook za otvaranje obavijesti, njihovo odbacivanje ni action dugmad. Te signale proslijedite iz notification intenta ili receivera koje vaša aplikacija kreira:
import io.kixo.sdk.Kixo
Kixo.logPushOpened(payload = pushPayload) // open
Kixo.logPushOpened(payload = pushPayload, actionId = "reply") // action-button tap
Kixo.logPushDismissed(payload = pushPayload) // swipe-awayReprodukcija sesije
Reproducirajte stvarnu vizualnu rekonstrukciju onoga što je korisnik vidio. Pri svakom snimanju SDK kodira komprimirani frejm ekrana (JPEG sliku) zajedno sa strukturnim snimkom hijerarhije viewova i šalje oboje — tako player u dashboardu može prikazati piksel-preciznu reprodukciju uz vremensku liniju interakcija. Replay za projekat konfigurirate u Kontrolna tabla → Postavke → Reprodukcija sesije. SDK automatski čita i osvježava tu projektnu politiku, uključujući maskiranje, režime snimanja i dozvolu za slanje preko mobilne mreže.
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)Kada je slanje preko mobilne mreže isključeno, replay na čekanju čeka dopuštenu mrežu.
Savjet
Maskirajte prije slanja. Kixo snima piksele, zato se maskiranje izvršava prije nego što bilo šta napusti uređaj. Polja za lozinku i email prepoznaju se automatski i zacrnjuju; tekst u strukturnim snimcima prolazi kroz PII filter; a svaki view koji označite sa setKixoMask(true) pretvara se u neprozirni pravougaonik u frejmu prije se JPEG kodira — njegovi pikseli nikad ne napuštaju uređaj. Ekrani u Jetpack Compose su po zadanim postavkama maskirani u cijelosti (pozovite setKixoMask(false) na vanjskom ComposeView da uključite ekran koji ste već pregledali). Operateri u dashboardu pregledaju replay player zajedno s vremenskom linijom događaja.
Prikupljanje podataka
SDK prikuplja podatke koji su uključeni u vašem projektu te događaje i svojstva koje šalje vaša aplikacija.
Otklanjanje grešaka
Kixo.diagnostics() vraća snapshot zdravstvenog stanja SDK-a samo za čitanje — korisno u skrivenom debug ekranu ili smoke testu. Odgovara na pitanje „zašto mi događaji ne prolaze?“ bez debuggera.
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 statePrisilno pokrenite flush iz testnog okruženja — blokira do timeoutMs dok traje mrežni round-trip:
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
Rute Activity / Fragment odmah proizvode screen_view događaje i strukturirane zapise screen_visit s metapodacima o zadržavanju i toku, bez dodatnog podešavanja. Za Jetpack Compose Navigation pozovite Kixo.screen iz LaunchedEffect vezanog za rutu — tada SDK vidi jedan događaj po odredištu, bez obzira na broj rekompozicija.
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 za pisanje koda
Javna površina SDK-a mala je i prilagođena code completionu — svaka metoda je na singletonu Kixo, svaki Kotlin primjer u ovom vodiču počinje sa import io.kixo.sdk.Kixo, a naš README sadrži blok „AI agent quick reference“ koji alati kao što su Claude Code, Cursor i Codex mogu direktno zalijepiti u svoj kontekst. Ako vaš agent zapne, ovo je kanonska polazna tačka:
// 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."Napomena
Svaki odjeljak iznad pisan je imajući taj način rada na umu — importi su uvijek eksplicitni, tipovi uvijek imenovani, a SDK singleton se nikad ne aliasira. Dajte ovu stranicu agentu i pustite ga da vodi.