Android SDK
Das Kixo Android SDK unterstützt Kotlin 2.0+ und Java, setzt minSdk 24 (Android 7.0) voraus und ist gegen compileSdk 35 gebaut. Für dein eigenes targetSdk bleibt die Host-App selbst verantwortlich. Ein einzelner Aufruf von Kixo.configure in deiner Application.onCreate erfasst Screens, Taps, Sitzungen, Abstürze und Lifecycle-Events automatisch. Für Push-Tracking ist die unten beschriebene FCM-Bridge erforderlich. Automatisches Tracking von Netzwerkanfragen ist im aktuellen Android-Release nicht enthalten. Das SDK unterstützt außerdem Session Replay, Identität und Ziele.
Schnellstart
Drei Dateien: Maven-Repository hinzufügen, Abhängigkeit hinzufügen und dann zwei Zeilen in deine Application-Unterklasse einfügen.
Build-Voraussetzungen: compileSdk 35, minSdk 24, Kotlin 2.0+ oder Java sowie 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")
}
}
}Hinweis
Damit ist die Analytics-Integration erledigt. Die Standard-Auto-Tracker sind standardmäßig aktiv; für Push brauchst du weiterhin die unten beschriebene FCM-Bridge. Einzelne Flags solltest du nur bei Bedarf mit KixoConfiguration.Builder(...) überschreiben.
In deine App einbinden
Das Kixo-Maven-Repository wird über GitHub Pages bereitgestellt. Füge es in settings.gradle.kts zusätzlich zu google() und mavenCentral() hinzu:
// 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")
}
}
}Deklariere die Abhängigkeit anschließend in deinem App-Modul:
// app/build.gradle.kts
dependencies {
implementation("io.kixo:kixo-android-sdk:0.1.20")
}Tipp
android.permission.INTERNET und android.permission.ACCESS_NETWORK_STATE sind bereits im SDK-Manifest enthalten. Die Benachrichtigungsberechtigungen bleiben Sache deiner App und werden erst deklariert, wenn du Push-Funktionen aktivierst.
Projekte mit mehreren Modulen
Die Gradle-Konfiguration implementation ist nicht transitiv: Wenn du implementation("io.kixo:kixo-android-sdk:0.1.20") in einem Bibliotheksmodul deklarierst, zum Beispiel :core_domain, wird Kixo für :app oder andere Consumer NICHT sichtbar. Es gibt zwei funktionierende Muster — wähle eines davon.
Muster A — jedes Modul, das Kixo aufruft, deklariert die Abhängigkeit selbst (empfohlen). hält den Classpath jedes Moduls schlank und vermeidet Kettenreaktionen bei Rebuilds. Verwende einen Versionskatalog (libs.kixo.sdk), damit du die Version nur an einer Stelle ändern musst.
// :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
}Muster B — über api(...) re-exportieren. Nur eine Deklaration, aber damit tauchen Kixo-Typen im öffentlichen ABI des Bibliotheksmoduls auf — jede Versionsänderung erzwingt dann einen Rebuild aller abhängigen Module. Verwende das nur, wenn die Bibliothek Kixo-Typen in ihren eigenen öffentlichen Signaturen nutzt, also zum Beispiel KixoDiagnostics aus einer Funktion zurückgibt.
// :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
}Warnung
Wenn in einem Modul beim Kompilieren Unresolved reference: Kixo auftaucht, fehlt diesem Modul die eigene Abhängigkeit auf das SDK. Füge die oben gezeigte implementation-Zeile hinzu oder verwende Muster B.
Initialisieren
Konfiguriere Kixo in deiner Application-Unterklasse — onCreate läuft vor jeder Activity, sodass jede Screen-Ansicht, jeder Tap und jedes Lifecycle-Event ab dem ersten Frame erfasst wird. Registriere Application mit android:name=".MyApp" in deinem Manifest.
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 feingranulare Einstellungen — etwa Auto-Tracking-Flags, Flush-Intervall, Replay-Sampling oder einen eigenen API-Host — erstellst du KixoConfiguration explizit:
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)Hinweis
Idempotent. Ein zweiter Aufruf von configure im selben Prozess ist ein als WARN protokolliertes No-op — das SDK behält die erste Konfiguration bei. Events, die dein Auth-Singleton sendet, bevor bevor configure aufgerufen wird, werden gepuffert (maximal 50) und abgespielt, sobald das SDK initialisiert ist. Du kannst Kixo.identify(...) also schon in globalem Code aufrufen, bevor Application.onCreate abgeschlossen ist.
Events erfassen
Drei Grundbausteine tragen den Großteil deiner Instrumentierung: track für Events, markGoal für Conversion-Signale und addBreadcrumb für Kontext, der nicht an einzelne Events gebunden ist.
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",
)Tipp
Ziele werden abgestuft bewertet. Als Ziel markierte Events fließen in die Aktivierungs-Funnels von Kixo und in den täglichen Cronjob zur Änderungserkennung ein. Fällt das Volumen eines Ziels im Wochenvergleich um 70 %, erscheint es im Dashboard mit dem Badge Muss geprüft werden. Verwende markGoal für die wenigen wirklich wichtigen Momente, track für alles andere.
Standard-Events
Komfortschicht über Kixo.track für Events, die Kixo am Namen erkennt — also exakte String-Keys, die der Standard-Event-Detektor im Backend abgleicht. Mit Validierung der Property-Struktur zur Compile-Zeit und einer zentralen Stelle für die Benennung.
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)Nutzer identifizieren
Ordne alle folgenden Events einer stabilen Nutzer-ID und einem Satz von Traits zu. Das Zusammenführen von anonymen und bekannten Nutzern übernimmt Kixo — Events, die vor identify erfasst wurden, werden nachträglich demselben Nutzer zugeordnet.
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()⚠️ Stolperfalle mit dem Dollarzeichen in Kotlin. Standard-Identity-Keys haben das Präfix $ ($email, $name, $first_name) — und in einem Kotlin-Stringliteral muss du das Dollarzeichen als "\$email" escapen. Wenn du "$email" schreibst, wird stattdessen deine Variable email interpoliert. Der Wert landet dann stillschweigend als Trait individuell und füllt die Audience-Spalten für E-Mail oder Name nie. Am einfachsten ist die typisierte Überladung (SDK 0.1.13+); damit ist dieser Fehler ausgeschlossen: Kixo.setUserProperty(StandardProperty.EMAIL, email).
Nutzer für die Segmentierung markieren
Verwende setUserProperty mit einem boolesch-Wert, um den Nutzer mit einem einfachen Ja/Nein-Merkmal zu versehen. Das Merkmal bleibt über App-Starts hinweg erhalten und kann für Segmente, E-Mail-Kampagnen und Chat-Abfragen genutzt werden — mehr als den SDK-Aufruf brauchst du nicht.
// 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",
))Properties werden über SharedPreferences appübergreifend gespeichert und automatisch an jedes ausgehende Event angehängt. Sag in Kixo Chat zum Beispiel "Sende eine Willkommens-E-Mail an Nutzer, bei denen subscribe true ist" — Kixo erstellt daraus das Segment und einen Vorlagenentwurf. Gelöscht werden sie bei Kixo.reset().
Standardkatalog für Properties
Reservierte Property-Schlüssel tragen das Präfix $, damit sie klar von deinen eigenen Traits getrennt sind. Der Katalog von Kixo umfasst 37 Schlüssel in 3 universellen Paketen (Identität, Geo, Lebenszyklus) und 5 B2B-Fachpaketen (Subscription, E-Commerce, Medien, Marktplatz, Loyalität). Setze einfach die Schlüssel, die zu deinem Produkt passen — das Dashboard passt sich an und zeigt nur die Pakete an, die du tatsächlich befüllst.
Identität
Immer relevant. Legt die Spalten im Profilkopf fest.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$email | String | Primäre E-Mail-Adresse, oft der Schlüssel zum Zusammenführen von Identitäten. |
$phone | String | Telefonnummer im E.164-Format. |
$name | String | Vollständiger Anzeigename. |
$first_name | String | Vorname. |
$last_name | String | Nachname. |
$avatar_url | String | Vollständige URL zum Avatarbild des Nutzers. |
Geo
Geografischer Kontext.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$country | String | Ländercode nach ISO 3166. |
$city | String | Stadtname. |
$region | String | Bundesland oder Provinz. |
$timezone | String | IANA-Zeitzone wie America/Los_Angeles. |
$language | String | IETF-Tag wie en oder ru-RU. |
$locale | String | Vollständiger Locale-Identifier. |
Lebenszyklus
Wann wir sie zuletzt gesehen haben.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$created | ISO8601 | Zeitpunkt der Registrierung oder Kontoerstellung. |
$last_seen | ISO8601 | Zeitpunkt der letzten Interaktion. |
Abonnement
Setzen, wenn dein Produkt Tarife hat.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$plan | String | Stufen-Slug — free, pro, enterprise. |
$subscription_status | String | active / trial / cancelled / past_due. |
$trial_ends | ISO8601 | Wann die aktuelle Testphase endet. |
$mrr | Zahl | Monatlich wiederkehrender Umsatz in der Kontowährung. |
$subscription_started | ISO8601 | Beginn des aktuellen Abonnements. |
E-Commerce
Setzen, wenn du Produkte verkaufst.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$lifetime_orders | Zahl | Anzahl abgeschlossener Bestellungen. |
$lifetime_revenue | Zahl | Gesamtausgaben. |
$aov | Zahl | Durchschnittlicher Bestellwert. |
$last_purchase | ISO8601 | Letzter erfolgreicher Kauf. |
$first_purchase | ISO8601 | Erster erfolgreicher Kauf. |
$cart_abandoned_count | Zahl | Gesamtzahl der Warenkorbabbrüche. |
Medien
Setzen, wenn du Inhalte veröffentlichst.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$content_tier | String | free / premium / paid. |
$subscribed_categories | CSV-String oder Array | Kategorien, denen der Nutzer folgt. |
$watch_time_total | Zahl | Gesamte Wiedergabezeit in Sekunden. |
$last_played | ISO8601 | Zeitpunkt des letzten Wiedergabestarts. |
Marktplatz
Setzen, wenn dein Produkt eine zweiseitige Plattform ist.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$seller_tier | String | Slug der Verkäuferstufe. |
$buyer_tier | String | Tier-Slug auf Käuferseite. |
$listings_count | Zahl | Aktive Einträge des Nutzers. |
$reviews_count | Zahl | Bewertungen, die der Nutzer erhalten hat. |
$verified | boolesch | KYC-Status. |
Loyalität
Für Engagement- und Bonusprogramme setzen.
| Schlüssel | Typ | Beschreibung |
|---|---|---|
$loyalty_points | Zahl | Aktuell einlösbarer Punktestand. |
$vip_level | String | VIP-Stufen-Slug. |
$referral_count | Zahl | Erfolgreiche Empfehlungen, die diesem Nutzer zugeschrieben werden. |
Tipp
Dein Muster ist nicht dabei? Verwende für Custom Traits einfach ungeprefxte Keys. Sie erscheinen im Dashboard im Bereich „Custom Traits“, ohne die Profilspalten zu überladen. Die fünf Vertical Packs oben sind bewusst gewählte Annahmen für die häufigsten B2B-Modelle — kundenspezifische Begriffe (z. B. shipping_plan) bleiben ohne Präfix.
Super-Properties
Schlüssel/Wert-Paare pro Sitzung, die automatisch an jedes ausgehende Event angehängt werden. Anders als identify-Traits, die die Identität beschreiben, stehen Super-Properties für den Sitzungskontext — etwa aktive A/B-Variante, Build-Flavor oder aktivierte Feature-Flags. Sie bleiben über App-Starts hinweg erhalten und werden bei reset() gelöscht. Bei Kollisionen haben die properties auf track immer Vorrang.
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-Benachrichtigungen
Es gibt zwei Integrationswege. Wähle A, wenn du FCM nutzt und die kürzeste funktionierende Lösung willst. Wähle B, wenn du bereits einen eigenen FirebaseMessagingService hast, den du nicht umbauen kannst, oder wenn du explizit steuern willst, welche FCM-Zustellungen Kixo sieht.
Option A — KixoFirebaseMessagingService erweitern (Auto-Tracking)
Erweitere KixoFirebaseMessagingService und rufe in deiner Überschreibung super.onMessageReceived(...) auf — Kixo sendet dann automatisch push_received (sichtbare Payload) oder push_silent (nur Daten). Die Basisklasse übernimmt außerdem die Registrierung von onNewToken, sofern du sie nicht überschreibst. Die Registrierung von AndroidManifest.xml bleibt unverändert gegenüber einem normalen FCM-Service.
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
}
}Hinweis
Kixo kompiliert diese optionale Klasse gegen Firebase Messaging, bringt Firebase aber nicht transitiv in deine App. Das SDK deklariert Firebase als compileOnly; eine App, die diese Option nutzt, muss daher bereits von firebase-messaging abhängen — wie jede App mit einem FCM-Receiver.
Option B — die manuelle API aus deinem eigenen FCM-Service aufrufen
Registriere dein FCM-Token über FirebaseMessagingService.onNewToken bei Kixo und protokolliere dann jede Zustellung explizit. Nutze diesen Weg, wenn Kixo nur einen Teil deiner FCM-Zustellungen sehen soll. Auf Android wird Zustellungstracking derzeit nur für FCM unterstützt.
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 bietet keinen universellen Lifecycle-Hook für das Öffnen, Verwerfen oder die Aktionsschaltflächen von Benachrichtigungen. Leite diese Signale daher aus den Notification-Intents oder Receivern weiter, die deine App selbst anlegt:
import io.kixo.sdk.Kixo
Kixo.logPushOpened(payload = pushPayload) // open
Kixo.logPushOpened(payload = pushPayload, actionId = "reply") // action-button tap
Kixo.logPushDismissed(payload = pushPayload) // swipe-awaySitzungswiedergabe
Replay zeigt eine visuelle Rekonstruktion dessen, was der Nutzer gesehen hat. Bei jeder Erfassung kodiert das SDK ein komprimiertes Bildschirmbild (ein JPEG-Bild) zusammen mit einem strukturellen Schnappschuss der View-Hierarchie und lädt beides hoch — so kann der Player im Dashboard eine pixelgenaue Wiedergabe neben der Interaktionszeitleiste darstellen. Konfiguriere Replay für das Projekt in Dashboard → Einstellungen → Sitzungswiedergabe. Das SDK liest diese Projektrichtlinie automatisch ein und aktualisiert sie regelmäßig, einschließlich Maskierung, Erfassungsmodi und der Freigabe für Uploads über Mobilfunk.
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)Wenn Uploads über Mobilfunk deaktiviert sind, wartet die Replay-Warteschlange auf ein zulässiges Netzwerk.
Tipp
Vor dem Hochladen maskieren. Kixo erfasst Pixel. Deshalb greift die Maskierung bevor, bevor irgendetwas das Gerät verlässt. Passwort- und E-Mail-Felder werden automatisch erkannt und geschwärzt, Text in strukturellen Schnappschüssen läuft durch einen PII-Filter, und jede View, die du mit setKixoMask(true) markierst, wird im Frame vor dem bevor des JPEG als deckendes Rechteck gerastert — ihre Pixel verlassen das Gerät nie. Screens in Jetpack Compose sind standardmäßig vollständig maskiert. Wenn du einen geprüften Screen einbeziehen willst, rufe setKixoMask(false) auf dem äußersten ComposeView auf. Im Dashboard prüfen Teammitglieder den Replay-Player zusammen mit der Ereigniszeitleiste.
Datenerfassung
Das SDK erfasst die in deinem Projekt aktivierten Daten sowie die Events und Properties, die deine App sendet.
Debugging
Kixo.diagnostics() liefert einen schreibgeschützten Snapshot des SDK-Zustands — praktisch für einen versteckten Debug-Screen oder einen Smoke-Test. Beantwortet „Warum kommen meine Events nicht an?“ ganz ohne Debugger.
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 stateErzwinge einen Flush aus deinem Test-Harness — blockiert bis zu timeoutMs für einen Netzwerk-Roundtrip:
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
Activity- und Fragment-Routen erzeugen sofort screen_view-Events und liefern ohne weiteres Zutun strukturierte screen_visit-Einträge mit Metadaten zu Verweildauer und Ablauf. Bei Navigation mit Jetpack Compose rufst du Kixo.screen in einem LaunchedEffect auf, das an die Route gebunden ist — dann sieht das SDK genau ein Event pro Ziel, unabhängig von der Zahl der Recompositionen.
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-Coding-Agenten
Die öffentliche Oberfläche des SDK ist klein und auf Code-Completion ausgelegt — jede Methode hängt am Singleton Kixo, jedes Kotlin-Beispiel in diesem Leitfaden beginnt mit import io.kixo.sdk.Kixo, und unser README enthält einen Block „AI agent quick reference“, den Tools wie Claude Code, Cursor und Codex direkt in ihren Kontext übernehmen können. Wenn dein Agent hängen bleibt, ist das der verlässliche Einstieg:
// 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."Hinweis
Alle Abschnitte oben sind auf diesen Ablauf zugeschnitten: Imports sind immer explizit, Typen immer ausgeschrieben, und das SDK-Singleton bekommt nie einen Alias. Gib diese Seite deinem Agenten und lass ihn damit arbeiten.