Hoppa till dokumentationen

Android SDK

Kixo Android SDK stöder Kotlin 2.0+ och Java, kräver minSdk 24 (Android 7.0) och är byggt mot compileSdk 35. Din app ansvarar fortfarande för sin egen targetSdk. Med ett enda anrop till Kixo.configure i din Application.onCreate spåras skärmar, tryck, sessioner, krascher och livscykelhändelser automatiskt. Push-spårning kräver FCM-bryggan som beskrivs nedan. Automatisk spårning av nätverksanrop ingår inte i den aktuella Android-versionen. SDK:t stöder också sessionsåterspelning, identitet och mål.

Snabbstart

Tre filer. Lägg till Maven-repot, lägg till beroendet och lägg sedan in två rader i din underklass av Application.

Byggkrav: compileSdk 35, minSdk 24, Kotlin 2.0+ eller Java samt Java 17-bytekod.

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri("https://raw.githubusercontent.com/kixoio/kixo-android-sdk/main/repo")
        }
    }
}

Obs!

Det är hela analysintegrationen. Standardspårare är aktiverade som standard, men push kräver fortfarande FCM-bryggan nedan. Skriv bara över enskilda flaggor med KixoConfiguration.Builder(...) när det behövs.

Lägg till i appen

Kixo Maven-repo ligger på GitHub Pages. Lägg till det tillsammans med google() och mavenCentral() i 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")
        }
    }
}

Deklarera sedan beroendet i appmodulen:

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

Tips

android.permission.INTERNET och android.permission.ACCESS_NETWORK_STATE ingår i SDK-manifestet. Behörigheter för notiser hanteras fortfarande av appen och deklareras när du väljer att använda pushfunktionerna.

Projekt med flera moduler

Gradles konfiguration implementation är inte transitiv: om du deklarerar implementation("io.kixo:kixo-android-sdk:0.1.20") i en biblioteksmodul, till exempel :core_domain, blir Kixo INTE synligt för :app eller någon annan konsument. Det finns två fungerande mönster — välj ett.

Mönster A — varje modul som anropar Kixo deklarerar beroendet själv (rekommenderas). Det håller klassökvägen minimal i varje modul och undviker ombyggnader som spiller över i kedjan. Använd en versionskatalog (libs.kixo.sdk) så att du bara ändrar versionen på ett ställe.

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
}

Mönster B — återexportera via api(...). En enda deklaration, men biblioteksmodulens publika ABI innehåller då Kixo-typer — varje versionshöjning tvingar fram ombyggnad av alla nedströmsmoduler. Använd bara detta när biblioteket återanvänder Kixo-typer i sina egna publika signaturer, till exempel returnerar KixoDiagnostics från en funktion.

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
}

Varning

Om du ser Unresolved reference: Kixo vid kompilering i en modul saknar den modulen ett eget beroende på SDK:t — lägg till raden med implementation ovan eller använd mönster B.

Initiera

Konfigurera Kixo i din underklass av ApplicationonCreate körs före alla aktiviteter, så varje skärmvisning, tryckning och livscykelhändelse fångas från första bildrutan. Registrera Application i manifestet med 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",
        )
    }
}

För finjusteringar som flaggor för autospårning, flushintervall, replay-sampling och anpassad API-värd skapar du en KixoConfiguration explicit:

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)

Obs!

Idempotent. Ett andra anrop till configure från samma process blir en WARN-loggad no-op — SDK:t behåller den första konfigurationen. Händelser som köas av din auth-singleton innan innan configure är på plats buffras upp till 50 stycken och spelas upp när SDK:t är inkopplat, så du kan anropa Kixo.identify(...) från en global innan Application.onCreate är klart.

Spåra händelser

Tre byggstenar står för merparten av instrumenteringen: track för händelser, markGoal för konverteringssignaler och addBreadcrumb för kontext som inte är en händelse.

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

Tips

Mål graderas. Markerade mål används i Kixo:s aktiveringstrattar och i det dagliga cron-jobbet för förändringsdetektering — om volymen för ett mål faller med 70 % vecka över vecka visas det i dashboarden med märkningen Behöver granskas. Använd markGoal för de få tillfällen som verkligen spelar roll, och track för allt annat.

Standardhändelser

Ett lager ovanpå Kixo.track för de händelser som Kixo känner igen på namn — exakta strängnycklar som backendens detektor för standardhändelser matchar. Ger validering av egenskapsformat vid kompilering och en enda källa för namngivningen.

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)

Identifiera användare

Knyt efterföljande händelser till ett stabilt användar-id och en uppsättning traits. Ihopkopplingen från anonym till känd användare sker i Kixo — händelser som fångas upp före identify tillskrivs i efterhand samma användare.

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

⚠️ Vanlig fallgrop med dollartecken i Kotlin. Standardnycklar för identitet har prefixet $ ($email, $name, $first_name) — och i en Kotlin-strängliteral måste du escap:a dollartecknet som "\$email". Skriver du "$email" interpoleras variabeln email, så värdet hamnar tyst som en anpassad-trait och fyller aldrig kolumnerna för e-post eller namn i Audience. Enklaste lösningen är att använda den typade överlagringen (SDK 0.1.13+), som inte går att få fel: Kixo.setUserProperty(StandardProperty.EMAIL, email).

Märk upp en användare för segmentering

Använd setUserProperty med ett boolesk-värde för att ge användaren en enkel ja/nej-tagg. Taggen ligger kvar mellan appstarter och används i segment, e-postkampanjer och frågor i chatten — utan någon extra konfiguration utöver anropet till SDK.

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

Egenskaperna sparas via SharedPreferences mellan appstarter och läggs automatiskt till på varje utgående händelse. Skriv till exempel "skicka ett välkomstmejl till användare där subscribe är true" i chatten — Kixo bygger segmentet och tar fram ett utkast till mall åt dig. Rensas vid Kixo.reset().

Standardkatalog för egenskaper

Reserverade egenskapsnycklar har prefixet $, så att de hålls åtskilda från dina egna traits. Kixo har en katalog med 37 nycklar i 3 universella paket (identitet, geografi, livscykel) och 5 B2B-paket för olika produktområden (prenumeration, e-handel, media, marknadsplats, lojalitet). Ange de som passar din produkt — dashboarden anpassar sig och visar bara de paket du faktiskt fyller med data.

Identitet

Alltid relevant. Anger kolumnerna i profilhuvudet.

NyckelTypBeskrivning
$emailsträngPrimär e-postadress, ofta nyckeln som används för att slå ihop identiteter.
$phonesträngTelefonnummer i E.164-format.
$namesträngFullständigt visningsnamn.
$first_namesträngFörnamn.
$last_namesträngEfternamn.
$avatar_urlsträngFullständig URL till användarens avatarbild.

Geografi

Geografisk kontext.

NyckelTypBeskrivning
$countrysträngLandskod enligt ISO 3166.
$citysträngStadsnamn.
$regionsträngDelstat eller provins.
$timezonesträngIANA-zon som America/Los_Angeles.
$languagesträngIETF-tagg som en eller ru-RU.
$localesträngFullständig språkversionsidentifierare.

Livscykel

När vi senast såg dem.

NyckelTypBeskrivning
$createdISO8601Tidpunkt för registrering eller kontoskapande.
$last_seenISO8601Tidpunkt för senaste aktivitet.

Prenumeration

Ange om produkten har abonnemang.

NyckelTypBeskrivning
$plansträngSlug för nivå — free, pro, enterprise.
$subscription_statussträngactive / trial / cancelled / past_due.
$trial_endsISO8601När den nuvarande provperioden löper ut.
$mrrtalMånatlig återkommande intäkt i kontots valuta.
$subscription_startedISO8601När den nuvarande prenumerationen började.

E-handel

Ange om ni säljer produkter.

NyckelTypBeskrivning
$lifetime_orderstalAntal slutförda beställningar.
$lifetime_revenuetalTotal kostnad.
$aovtalGenomsnittligt ordervärde.
$last_purchaseISO8601Senaste genomförda köp.
$first_purchaseISO8601Första genomförda köp.
$cart_abandoned_counttalTotalt antal övergivna varukorgar.

Media

Ange om ni publicerar innehåll.

NyckelTypBeskrivning
$content_tiersträngfree / premium / paid.
$subscribed_categoriesCSV-sträng eller arrayKategorier som användaren följer.
$watch_time_totaltalTotal visningstid i sekunder.
$last_playedISO8601Senaste uppspelningsstart.

Marknadsplats

Ange om ni är en plattform med två sidor.

NyckelTypBeskrivning
$seller_tiersträngSlug för säljarens nivå.
$buyer_tiersträngSlug för köparsidan.
$listings_counttalAktiva annonser som användaren äger.
$reviews_counttalOmdömen som användaren har fått.
$verifiedbooleskKYC-status.

Lojalitet

Används för engagemangs- och belöningsprogram.

NyckelTypBeskrivning
$loyalty_pointstalAktuellt saldo för inlösbara poäng.
$vip_levelsträngSlug för VIP-nivå.
$referral_counttalLyckade rekommendationer som tillskrivits den här användaren.

Tips

Saknas ditt mönster? Använd vanliga nycklar för anpassade egenskaper. De visas i dashboardens panel för Custom Traits utan att ta plats i profilkolumnerna. De fem vertikalpaketen ovan är genomtänkta gissningar om de vanligaste B2B-uppläggen — kundspecifik terminologi, till exempel shipping_plan, lämnas utan prefix.

Superegenskaper

Nyckel/värde-par per session som automatiskt läggs till på varje utgående händelse. Till skillnad från identify traits, som beskriver identitet, beskriver super-properties sessionens kontext — aktiv A/B-variant, build flavor och aktiverade feature flags. De sparas mellan appstarter och rensas vid reset(). Vid krock vinner alltid properties per händelse på 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()

Pushnotiser

Två integrationsvägar. Välj A om du använder FCM och vill ha kortast möjliga väg till en fungerande lösning. Välj B om du redan har en anpassad FirebaseMessagingService som du inte kan bygga om, eller om du vill styra exakt vilka FCM-leveranser Kixo ska se.

Alternativ A — utöka KixoFirebaseMessagingService (automatisk spårning)

Utöka KixoFirebaseMessagingService och anropa super.onMessageReceived(...) från din override — då skickar Kixo automatiskt push_received (synlig payload) eller push_silent (endast data). Basklassen hanterar också registrering av onNewToken om du inte skriver över den. Registrering av AndroidManifest.xml fungerar i övrigt som i en vanlig FCM-tjänst.

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
    }
}

Obs!

Kixo kompilerar den här valfria klassen mot Firebase Messaging, men lägger inte till Firebase transitivt i din app. SDK:t deklarerar Firebase som compileOnly; en app som väljer det här alternativet måste därför redan bero på firebase-messaging, precis som för alla FCM-mottagare.

Alternativ B — anropa det manuella API:t från din egen FCM-tjänst

Registrera din FCM-token hos Kixo via FirebaseMessagingService.onNewToken och logga sedan varje leverans explicit. Välj den här vägen om du bara vill att Kixo ska se en delmängd av FCM-leveranserna. Leveransspårning på Android stöder för närvarande bara 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 exponerar ingen generell livscykelkrok för öppningar, avvisningar eller åtgärdsknappar i notiser. Vidarebefordra i stället de signalerna från de notis-intent eller receivers som appen skapar:

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

Sessionsåterspelning

Återspela en verklig, visuell rekonstruktion av det användaren såg. Vid varje inspelning kodar SDK:t en komprimerad bildruta av skärmen (en JPEG-bild) tillsammans med en strukturell ögonblicksbild av vyhierarkin och laddar upp båda, så att spelaren i dashboarden kan återge uppspelningen med pixelprecision sida vid sida med tidslinjen för interaktioner. Konfigurera replay för projektet i Översikt → Inställningar → Sessionsrepris. SDK:t läser automatiskt in och uppdaterar projektets policy, inklusive maskering, inspelningslägen och tillåtelse för uppladdning via mobilnät.

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)

När uppladdning via mobilnät är avstängd väntar köad replay tills ett tillåtet nätverk är tillgängligt.

Tips

Maskera före uppladdning. Kixo fångar pixlar, så maskeringen sker innan något lämnar enheten. Lösenords- och e-postfält upptäcks och maskeras automatiskt, text i strukturella ögonblicksbilder passerar genom ett PII-filter, och varje vy som du markerar med setKixoMask(true) rasteriseras till en ogenomskinlig rektangel i bildrutan innan JPEG-kodningen sker — dess pixlar lämnar aldrig enheten. Skärmar i Jetpack Compose maskeras i sin helhet som standard (anropa setKixoMask(false) på den yttersta ComposeView om du vill inkludera en skärm som du har granskat). Operatörer granskar återspelningen i spelaren tillsammans med händelsetidslinjen i dashboarden.

Datainsamling

SDK:t samlar in den data som är aktiverad i projektet samt de händelser och egenskaper som appen skickar.

Felsökning

Kixo.diagnostics() returnerar en skrivskyddad ögonblicksbild av SDK:ts hälsa — praktiskt i en dold felsökningsskärm eller ett smoke test. Svarar på frågan "varför kommer inga händelser fram?" utan debugger.

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

Tvinga fram en flush från testhärvan — blockerar i upp till timeoutMs för en nätverksrunda:

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

Rutter för Activity och Fragment ger direkt screen_view-händelser och strukturerade screen_visit-poster med metadata för vistelsetid och flöde. För Jetpack Compose Navigation skickar du Kixo.screen från en LaunchedEffect nycklad på rutten — då ser SDK:t en händelse per destination, oavsett hur många omkompositioner som sker.

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-kodassistenter

SDK:ts publika yta är liten och utformad för kodkomplettering — alla metoder finns på singletonen Kixo, alla Kotlin-exempel i den här guiden börjar med import io.kixo.sdk.Kixo, och vår README innehåller ett block med "AI agent quick reference" som verktyg som Claude Code, Cursor och Codex kan klistra in direkt i sitt sammanhang. Om din agent kör fast är det här den kanoniska starten:

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."

Obs!

Alla avsnitt ovan är skrivna för det arbetsflödet — importer är alltid explicita, typer är alltid utskrivna och SDK-singletonen aliasas aldrig. Ge sidan till din agent och låt den driva arbetet.