Idi na dokumentaciju

Android SDK

Kixo Android SDK podržava Kotlin 2.0+ i Java, zahteva minSdk 24 (Android 7.0) i kompajliran je uz compileSdk 35. Vaša host aplikacija i dalje sama brine o svom targetSdk. Jedan poziv Kixo.configure u vašem Application.onCreate automatski prati ekrane, dodire, sesije, padove aplikacije i događaje životnog ciklusa. Za praćenje push poruka potreban je FCM most opisan ispod. Automatsko praćenje mrežnih zahteva nije deo trenutnog Android izdanja. SDK podržava i session replay, identitet i ciljeve.

Brzi početak

Tri fajla. Dodajte Maven repozitorijum, dodajte zavisnost, pa ubacite dve linije u svoju podklasu Application.

Zahtevi za build: compileSdk 35, minSdk 24, Kotlin 2.0+ ili Java i 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 cela analytics integracija. Standardni auto-tracker-i su podrazumevano uključeni; za push je i dalje potreban FCM most ispod. Pojedinačne flag-ove menjajte preko KixoConfiguration.Builder(...) samo kada je potrebno.

Dodajte u aplikaciju

Kixo Maven repozitorijum hostuje se na GitHub Pages. Dodajte ga uz google() i mavenCentral() u settings.gradle.kts:

kotlin
// 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 dodajte zavisnost u modul aplikacije:

kotlin
// app/build.gradle.kts
dependencies {
    implementation("io.kixo:kixo-android-sdk:0.1.20")
}

Savet

android.permission.INTERNET i android.permission.ACCESS_NETWORK_STATE su uključeni u manifest SDK-a. Dozvole za notifikacije i dalje kontroliše vaša aplikacija i prijavljuju se kada uključite push funkcije.

Projekti sa više modula

Gradle konfiguracija implementation je nije tranzitivno: ako u bibliotečkom modulu (npr. :core_domain) deklarišete implementation("io.kixo:kixo-android-sdk:0.1.20"), to NE čini Kixo vidljivim za :app niti za bilo kog drugog potrošača. Postoje dva ispravna obrasca — izaberite jedan.

Obrazac A — svaki modul koji poziva Kixo deklariše ga sam (preporučeno). Održava classpath svakog modula malim i sprečava kaskadne rebuild-ove. Koristite version catalog (libs.kixo.sdk) da verziju menjate na jednom mestu.

kotlin
// :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 — reeksport preko api(...). Jedna deklaracija, ali javni ABI bibliotečkog modula tada uključuje Kixo tipove — svaka promena verzije pokreće rebuild svih downstream modula. Koristite ovo samo kada biblioteka koristi Kixo tipove i u svojim javnim potpisima, na primer kada funkcija vraća KixoDiagnostics.

kotlin
// :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 sopstvena zavisnost od SDK-a — dodajte implementation red iznad ili koristite obrazac B.

Inicijalizacija

Podesite Kixo iz svoje podklase ApplicationonCreate se izvršava pre bilo koje activity, pa se svaki prikaz ekrana, dodir i događaj životnog ciklusa beleži od prvog kadra. Registrujte Application u manifestu pomoću android:name=".MyApp".

kotlin
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 detaljna podešavanja (flagove za automatsko praćenje, učestalost flush-a, replay sampling, prilagođeni API host) eksplicitno napravite KixoConfiguration:

kotlin
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 samo se zabeleži kao WARN i ne radi ništa — SDK zadržava prvu konfiguraciju. Događaji koje vaš auth singleton stavi u red pre nego što pre stigne do configure čuvaju se u baferu (do 50) i reprodukuju kada se SDK poveže, pa Kixo.identify(...) možete da pozovete iz globalnog konteksta i pre nego što se Application.onCreate završi.

Pratite događaje

Tri osnove nose najveći deo vaše instrumentacije: track za događaje, markGoal za signale konverzije i addBreadcrumb za kontekst van događaja.

kotlin
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",
)

Savet

Ciljevi se ocenjuju. Označeni ciljevi ulaze u Kixo levke aktivacije i dnevni cron za detekciju promena — cilj čiji obim padne 70% u odnosu na prethodnu nedelju pojaviće se u dashboardu sa oznakom Potrebna provera. Koristite markGoal za nekoliko ključnih trenutaka, a track za sve ostalo.

Standardni događaji

Tanki sloj preko Kixo.track za događaje koje Kixo prepoznaje po nazivu — doslovne string ključeve koje backend detektor standardnih događaja prepoznaje. Dobijate proveru oblika svojstava u vreme kompajliranja i jedno mesto istine za imenovanje.

kotlin
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)

Identifikujte korisnike

Povežite naredne događaje sa stabilnim ID-jem korisnika i skupom trait-ova. Spajanje anonimnog i poznatog identiteta radi Kixo — događaji zabeleženi pre identify naknadno se pripisuju istom korisniku.

kotlin
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()

⚠️ Zamka sa znakom dolara u Kotlinu. Standardni identitetski ključevi imaju prefiks $ ($email, $name, $first_name) — a u Kotlin string literalu mora znak dolara morate da escape-ujete kao "\$email". Ako napišete "$email", interpolira se promenljiva email, pa vrednost neprimetno završi kao trait prilagođeno i nikada ne popuni kolone za email / ime u Audience. Najjednostavnije rešenje je typed overload (SDK 0.1.13+), koji praktično ne može da se pogreši: Kixo.setUserProperty(StandardProperty.EMAIL, email).

Označite korisnika za segmentaciju

Koristite setUserProperty sa vrednošću tipa logička vrednost da korisniku dodelite jednostavnu da/ne oznaku. Oznaka ostaje sačuvana između pokretanja aplikacije i koristi se za segmente, email kampanje i upite u chatu — bez dodatnog podešavanja osim SDK poziva.

kotlin
// 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 preko SharedPreferences između pokretanja aplikacije i automatski dodaju svakom odlaznom događaju. U chatu možete da kažete nešto poput "pošalji imejl dobrodošlice korisnicima gde je subscribe true" — Kixo će za vas napraviti segment i pripremiti šablon. Brišu se pri Kixo.reset().

Standardni katalog svojstava

Rezervisani ključevi svojstava nose prefiks $ kako bi bili odvojeni od vaših prilagođenih osobina. Kixo katalog obuhvata 37 ključeva u 3 univerzalna paketa (identitet, geo, životni ciklus) i 5 B2B vertikalnih paketa (pretplata, e-trgovina, mediji, tržište, program lojalnosti). Podesite samo ono što je relevantno za vaš proizvod — dashboard se prilagođava i prikazuje samo pakete koje popunite.

Identitet

Uvek relevantno. Podešava kolone zaglavlja profila.

KljučTipOpis
$emailniskaPrimarna imejl adresa, često glavni ključ za povezivanje identiteta.
$phoneniskaBroj telefona u formatu E.164.
$nameniskaPuno ime za prikaz.
$first_nameniskaIme.
$last_nameniskaPrezime.
$avatar_urlniskaPun URL do korisnikove avatar slike.

Geo

Geografski kontekst.

KljučTipOpis
$countryniskaISO 3166 kod države.
$cityniskaNaziv grada.
$regionniskaDržava ili pokrajina.
$timezoneniskaIANA zona, na primer America/Los_Angeles.
$languageniskaIETF oznaka, na primer en ili ru-RU.
$localeniskaPuni identifikator lokalizacije.

Životni ciklus

Kada smo ga videli.

KljučTipOpis
$createdISO8601Vreme registracije ili otvaranja naloga.
$last_seenISO8601Vreme poslednje interakcije.

Pretplata

Podesite ako vaš proizvod ima planove.

KljučTipOpis
$planniskaSlug nivoa — free, pro, enterprise.
$subscription_statusniskaactive / trial / cancelled / past_due.
$trial_endsISO8601Kada ističe trenutni probni period.
$mrrbrojMesečni ponavljajući prihod u valuti naloga.
$subscription_startedISO8601Kada je počela trenutna pretplata.

E-trgovina

Podesite ako prodajete proizvode.

KljučTipOpis
$lifetime_ordersbrojBroj završenih porudžbina.
$lifetime_revenuebrojUkupna potrošnja.
$aovbrojProsečna vrednost porudžbine.
$last_purchaseISO8601Najnovija uspešna kupovina.
$first_purchaseISO8601Prva uspešna kupovina.
$cart_abandoned_countbrojUkupan broj napuštanja korpe.

Mediji

Podesite ako objavljujete sadržaj.

KljučTipOpis
$content_tierniskafree / premium / paid.
$subscribed_categoriesCSV string ili nizKategorije koje korisnik prati.
$watch_time_totalbrojUkupno vreme gledanja u sekundama.
$last_playedISO8601Najnovije pokretanje reprodukcije.

Tržište

Podesite ako ste platforma sa dve strane.

KljučTipOpis
$seller_tierniskaSlug nivoa na strani prodavca.
$buyer_tierniskaSlug paketa na strani kupca.
$listings_countbrojAktivni oglasi koje korisnik poseduje.
$reviews_countbrojRecenzije koje je korisnik dobio.
$verifiedlogička vrednostKYC status.

Program lojalnosti

Podesite ako koristite programe angažovanja i nagrađivanja.

KljučTipOpis
$loyalty_pointsbrojTrenutni raspoloživi saldo poena.
$vip_levelniskaSlug VIP nivoa.
$referral_countbrojUspešne preporuke pripisane ovom korisniku.

Savet

Ne vidite svoj obrazac? Za prilagođene trait-ove koristite obične ključeve. Prikazuju se u panelu Custom Traits na dashboardu, bez zagušenja kolona profila. Pet vertikalnih paketa iznad su promišljene pretpostavke o najčešćim B2B modelima — terminologija specifična za korisnika (npr. shipping_plan) ostaje bez prefiksa.

Super-svojstva

Parovi ključ/vrednost na nivou sesije koji se automatski dodaju svakom odlaznom događaju. Za razliku od identify trait-ova, koji opisuju identitet, super-properties opisuju kontekst sesije — aktivnu A/B varijantu, build flavor i uključene feature flag-ove. Ostaju sačuvani između pokretanja aplikacije; brišu se pri reset(). Ako dođe do preklapanja, prednost uvek imaju properties zadati po događaju na track.

kotlin
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 obaveštenja

Postoje dva puta integracije. Izaberite A ako koristite FCM i želite najkraće funkcionalno podešavanje; izaberite B ako već imate prilagođeni FirebaseMessagingService koji ne možete da restrukturirate ili želite eksplicitnu kontrolu nad tim koje FCM isporuke Kixo vidi.

Opcija A — nasledite KixoFirebaseMessagingService (automatsko praćenje)

Nasledite KixoFirebaseMessagingService i iz svog override-a pozovite super.onMessageReceived(...) — Kixo automatski emituje push_received (vidljiv payload) ili push_silent (samo podaci). Bazna klasa obrađuje i registraciju za onNewToken ako je sami ne override-ujete. Registracija za AndroidManifest.xml ostaje ista kao kod običnog FCM servisa.

kotlin
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 kompajlira ovu opcionu klasu uz Firebase Messaging, ali ne dodaje Firebase tranzitivno vašoj aplikaciji. SDK deklariše Firebase kao compileOnly; aplikacija koja koristi ovu opciju već mora da zavisi od firebase-messaging, kao i svaki FCM receiver.

Opcija B — pozovite ručni API iz svog FCM servisa

Registrujte FCM token u Kixo preko FirebaseMessagingService.onNewToken, a zatim eksplicitno beležite svaku isporuku. Ovaj pristup koristite kada želite da Kixo vidi samo deo FCM isporuka. Android isporuka trenutno podržava samo FCM.

kotlin
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 izlaže univerzalni lifecycle hook za otvaranje notifikacija, odbacivanje niti dugmad za akcije. Prosledite te signale iz notification intent-a ili receiver-a koje vaša aplikacija kreira:

kotlin
import io.kixo.sdk.Kixo

Kixo.logPushOpened(payload = pushPayload)            // open
Kixo.logPushOpened(payload = pushPayload, actionId = "reply")  // action-button tap
Kixo.logPushDismissed(payload = pushPayload)         // swipe-away

Snimak sesije

Replay daje stvarnu vizuelnu rekonstrukciju onoga što je korisnik video. Pri svakom snimanju SDK enkoduje kompresovani kadar ekrana (JPEG sliku) zajedno sa strukturnim snimkom hijerarhije prikaza i otprema oba, tako da plejer u dashboardu može da prikaže piksel-preciznu reprodukciju uz vremensku liniju interakcija. Replay za projekat podesite u Kontrolna tabla → Podešavanja → Snimanje sesije. SDK tu politiku projekta automatski učitava i osvežava, uključujući maskiranje, režime snimanja i dozvolu za otpremanje preko mobilne mreže.

kotlin
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 otpremanje preko mobilne mreže isključeno, replay na čekanju ostaje dok se ne pojavi dozvoljena mreža.

Savet

Maskirajte pre otpremanja. Kixo snima piksele, pa se maskiranje primenjuje pre nego što bilo šta napusti uređaj. Polja za lozinku i e-adresu prepoznaju se automatski i rediguju; tekst u strukturnim snimcima prolazi kroz PII filter; a svaki view koji označite sa setKixoMask(true) rasterizuje se kao neprovidan pravougaonik u kadru pre nego što se JPEG enkoduje — njegovi pikseli nikada ne napuštaju uređaj. Ekrani u Jetpack Compose su podrazumevano u celosti maskirani (pozovite setKixoMask(false) na spoljašnjem ComposeView da uključite ekran koji ste proverili). Operateri u dashboardu pregledaju replay plejer zajedno sa vremenskom linijom događaja.

Prikupljanje podataka

SDK beleži podatke koji su uključeni u projektu, kao i događaje i svojstva koje vaša aplikacija šalje.

Otklanjanje problema

Kixo.diagnostics() vraća pregled stanja SDK-a samo za čitanje — korisno na skrivenom debug ekranu ili u smoke testu. Odgovara na pitanje „zašto mi događaji ne prolaze?“ bez debugger-a.

kotlin
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 state

Prinudno pokrenite flush iz test harness-a — blokira do timeoutMs tokom jednog mrežnog round-trip-a:

kotlin
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 screen_visit zapise sa metapodacima o zadržavanju i toku, bez dodatnog podešavanja. Za Jetpack Compose Navigation pozovite Kixo.screen iz LaunchedEffect vezanog za rutu — SDK tada vidi jedan događaj po odredištu, bez obzira na broj rekompozicija.

kotlin
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 kodiranje

Javna površina SDK-a je mala i prilagođena code completion-u — svaka metoda je na singletonu Kixo, svaki Kotlin primer 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 da ubace u svoj kontekst. Ako vam se agent zaglavi, evo kanonske početne tačke:

kotlin
// 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 odeljak iznad napisan je za taj tok rada — importi su uvek eksplicitni, tipovi su uvek imenovani, a SDK singleton nikada nema alias. Prosledite ovu stranicu svom agentu i pustite ga da vodi.