Android SDK
Kixo Android SDK поддржува Kotlin 2.0+ и Java, бара minSdk 24 (Android 7.0) и е изграден врз compileSdk 35. Вашата host апликација и понатаму е одговорна за сопствениот targetSdk. Еден повик до Kixo.configure во вашата Application.onCreate автоматски следи екрани, допири, сесии, падови и lifecycle настани. За push tracking е потребен FCM bridge опишан подолу. Автоматско следење на мрежни барања не е дел од тековното Android издание. SDK поддржува и session replay, identity и goals.
Брз почеток
Три датотеки. Додајте го Maven repo-то, додајте ја зависноста, па внесете две линии во вашата поткласа на Application.
Потребно за build: compileSdk 35, minSdk 24, Kotlin 2.0+ или Java, и 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")
}
}
}Забелешка
Тоа е целата интеграција за аналитика. Стандардните auto-tracker-и се вклучени по дифолт; за push и понатаму е потребен FCM bridge подолу. Менувајте поединечни знаменца со KixoConfiguration.Builder(...) само кога навистина треба.
Додајте во апликацијата
Kixo Maven repo е хостиран на GitHub Pages. Додајте го покрај google() и mavenCentral() во 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")
}
}
}Потоа декларирајте ја зависноста во app модулот:
// app/build.gradle.kts
dependencies {
implementation("io.kixo:kixo-android-sdk:0.1.20")
}Совет
android.permission.INTERNET и android.permission.ACCESS_NETWORK_STATE се вклучени во manifest-от на SDK. Дозволите за известувања и понатаму ги контролира вашата апликација и се декларираат кога ќе се вклучите во push функционалностите.
Проекти со повеќе модули
Конфигурацијата implementation во Gradle е не е транзитивно: ако декларирате implementation("io.kixo:kixo-android-sdk:0.1.20") во library модул (на пр. :core_domain), тоа НЕ го прави Kixo видлив за :app ниту за кој било друг потрошувач. Работат две шеми — изберете една.
Pattern A — секој модул што повикува Kixo сам го декларира (препорачано). Го одржува classpath-от на секој модул минимален и спречува верижни rebuild-и. Користете version catalog (libs.kixo.sdk) за верзијата да ја менувате на едно место.
// :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
}Pattern B — реекспортирајте преку api(...). Една декларација, но јавниот ABI на library модулот сега вклучува Kixo типови — секое менување на верзијата предизвикува rebuild на сите downstream модули. Користете го ова само ако библиотеката повторно ги користи Kixo типовите во своите јавни потписи (на пр. враќа 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
}Предупредување
Ако при компајлирање во некој модул гледате Unresolved reference: Kixo, тој модул нема сопствена зависност од SDK — додајте ја implementation линијата погоре или користете Pattern B.
Иницијализација
Конфигурирајте го Kixo во вашата поткласа на Application — onCreate се извршува пред која било activity, па секој преглед на екран, допир и lifecycle настан се снима уште од првиот кадар. Регистрирајте го Application во manifest со 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",
)
}
}За попрецизни поставки (auto-track знаменца, ритам на flush, семплирање за replay, прилагоден API host), експлицитно изградете 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)Забелешка
Идемпотентно. Втор повик до configure од истиот process е no-op запишан како WARN — SDK ја задржува првата конфигурација. Настаните што вашиот auth singleton ги ставил во редица пред да се вчитаат пред и configure се баферираат (до 50) и се праќаат штом SDK ќе се поврзе, па можете да повикате Kixo.identify(...) од глобален контекст пред да заврши Application.onCreate.
Следете настани
Три примитиви го носат најголемиот дел од вашата инструментaција: track за настани, markGoal за сигнали за конверзија и addBreadcrumb за контекст што не е настан.
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",
)Совет
Целите се оценуваат. Обележаните цели ги напојуваат activation funnel-ите во Kixo и дневниот cron за откривање промени — цел чиј обем ќе падне 70% во однос на претходната недела се појавува во вашиот dashboard со ознака Потребен е преглед. Користете markGoal за неколкуте клучни моменти; track за сè друго.
Стандардни настани
Синтаксички шеќер над Kixo.track за настаните што Kixo ги препознава по име — дословни string клучеви што ги совпаѓа детекторот за стандардни настани на backend-от. Проверка на shape на својствата уште при компајлирање и едно изворно место за именување.
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)Идентификувајте корисници
Поврзете ги следните настани со стабилен кориснички id и збир на traits. Спојувањето од анонимен во познат корисник се прави во Kixo — настаните снимени пред identify ретроактивно се припишуваат на истиот корисник.
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()⚠️ Замка со dollar-знакот во Kotlin. Стандардните identity клучеви имаат префикс $ ($email, $name, $first_name) — а во Kotlin литерал мора мора да го escape-нете знакот dollar како "\$email". Ако напишете "$email", ќе се изврши string interpolation со вашата променлива email, па вредноста тивко ќе заврши како trait прилагодено и никогаш нема да ги пополни колоните за email / name во Audience. Наједноставно решение е да го користите typed overload-от (SDK 0.1.13+), каде што нема простор за грешка: Kixo.setUserProperty(StandardProperty.EMAIL, email).
Означете корисник за сегментација
Користете setUserProperty со вредност boolean за да додадете едноставна да/не ознака на корисникот. Ознаката останува и по повторно стартување и се користи за сегменти, email кампањи и chat пребарувања — без дополнително местење освен повикот кон 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",
))Својствата се зачувуваат преку SharedPreferences и по повторно стартување, и автоматски се прикачуваат на секој исходен настан. Во chat можете да кажете нешто како "испрати welcome email до корисници каде subscribe is true" — Kixo ќе го изгради сегментот и ќе ви подготви шаблон. Се чистат на Kixo.reset().
Стандарден каталог на својства
Резервираните клучеви на својства имаат префикс $, за да бидат одвоени од вашите сопствени traits. Каталогот на Kixo опфаќа 37 клучеви во 3 универзални пакети (идентитет, гео, животен циклус) и 5 вертикални B2B пакети (претплата, е-трговија, медиуми, пазар, лојалност). Поставете ги само оние што важат за вашиот производ — контролниот панел се приспособува и ги прикажува само пакетите што ги пополнувате.
Identity
Секогаш е релевантно. Ги поставува колоните во заглавјето на профилот.
| Клуч | Тип | Опис |
|---|---|---|
$email | низа | Примарна е-пошта, често клучот за спојување при поврзување идентитети. |
$phone | низа | Телефонски број во E.164 формат. |
$name | низа | Целосно прикажано име. |
$first_name | низа | Име. |
$last_name | низа | Презиме. |
$avatar_url | низа | Целосна URL до сликата за аватар на корисникот. |
Geo
Географски контекст.
| Клуч | Тип | Опис |
|---|---|---|
$country | низа | Код на држава според ISO 3166. |
$city | низа | Име на град. |
$region | низа | Сојузна држава или провинција. |
$timezone | низа | IANA зона како America/Los_Angeles. |
$language | низа | IETF tag како en или ru-RU. |
$locale | низа | Целосен идентификатор на locale. |
Животен циклус
Кога сме го виделе.
| Клуч | Тип | Опис |
|---|---|---|
$created | ISO8601 | Време на регистрација или креирање сметка. |
$last_seen | ISO8601 | Време на последна интеракција. |
Претплата
Поставете го ако вашиот производ има планови.
| Клуч | Тип | Опис |
|---|---|---|
$plan | низа | Slug на ниво — free, pro, enterprise. |
$subscription_status | низа | active / trial / cancelled / past_due. |
$trial_ends | ISO8601 | Кога истекува тековниот пробен период. |
$mrr | број | Месечен повторлив приход во валутата на сметката. |
$subscription_started | ISO8601 | Кога започнала тековната претплата. |
Е-трговија
Поставете го ако продавате производи.
| Клуч | Тип | Опис |
|---|---|---|
$lifetime_orders | број | Број на завршени нарачки. |
$lifetime_revenue | број | Вкупна потрошувачка. |
$aov | број | Просечна вредност на нарачка. |
$last_purchase | ISO8601 | Најнова успешна нарачка. |
$first_purchase | ISO8601 | Прво успешно купување. |
$cart_abandoned_count | број | Вкупен број напуштени кошнички. |
Медиуми
Поставете го ако објавувате содржина.
| Клуч | Тип | Опис |
|---|---|---|
$content_tier | низа | free / premium / paid. |
$subscribed_categories | CSV string или низа | Категории што ги следи корисникот. |
$watch_time_total | број | Вкупно време на гледање во секунди. |
$last_played | ISO8601 | Најново започнување репродукција. |
Пазар
Поставете го ако сте двострана платформа.
| Клуч | Тип | Опис |
|---|---|---|
$seller_tier | низа | Slug на ниво од страната на продавачот. |
$buyer_tier | низа | Slug на ниво од страната на купувачот. |
$listings_count | број | Активни огласи што ги поседува корисникот. |
$reviews_count | број | Рецензии што ги има добиено корисникот. |
$verified | boolean | KYC статус. |
Лојалност
Поставете го ако имате програми за ангажман и награди.
| Клуч | Тип | Опис |
|---|---|---|
$loyalty_points | број | Тековно салдо на искористливи поени. |
$vip_level | низа | Slug на VIP ниво. |
$referral_count | број | Успешни препораки припишани на овој корисник. |
Совет
Не го гледате вашиот шаблон? Користете bare keys за custom traits. Тие се појавуваат во панелот Custom Traits во аналитичкиот панел без да ги полнат колоните на профилот. Петте вертикални пакети погоре се насочени претпоставки за најчестите B2B модели — customer-specific terminology (на пр. shipping_plan) останува bare.
Super-properties
Клуч/вредност парови по сесија што автоматски се прикачуваат на секој исходен настан. Се разликуваат од traits identify (кои го опишуваат идентитетот); super-properties го опишуваат контекстот на сесијата — активна A/B варијанта, build flavor, вклучени feature flags. Се задржуваат и по повторно стартување; се чистат на reset(). При судир, предност секогаш имаат properties по настан на 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 известувања
Постојат две патеки за интеграција. Изберете A ако користите FCM и сакате најкратко работно поставување; изберете B ако веќе имате прилагоден FirebaseMessagingService што не можете да го преструктурирате или сакате експлицитна контрола врз тоа кои FCM испораки ги гледа Kixo.
Option A — наследете KixoFirebaseMessagingService (auto-tracking)
Наследете KixoFirebaseMessagingService и повикајте super.onMessageReceived(...) од вашиот override — Kixo автоматски испраќа push_received (видлив payload) или push_silent (само податоци). Базната класа исто така се грижи за регистрацијата на onNewToken ако не ја override-нете. Регистрацијата на AndroidManifest.xml останува иста како кај обичен 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
}
}Забелешка
Kixo ја компајлира оваа опционална класа со Firebase Messaging, но не додава Firebase транзитивно во вашата апликација. SDK го декларира Firebase како compileOnly; апликација што ја избира оваа опција веќе мора да зависи од firebase-messaging, како и секој FCM receiver.
Option B — повикајте manual API од вашиот FCM service
Регистрирајте го FCM token-от во Kixo преку FirebaseMessagingService.onNewToken, па секоја испорака евидентирајте ја експлицитно. Оваа патека користете ја ако сакате Kixo да гледа само дел од FCM испораките. Android delivery моментално поддржува само 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 не нуди универзален lifecycle hook за отворања, отфрлања или action копчиња на известувања. Проследете ги тие сигнали од notification intent-ите или receiver-ите што ги креира вашата апликација:
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Репродукција на сесија
Replay прикажува реална визуелна реконструкција на тоа што го видел корисникот. При секое снимање, SDK енкодира компресиран кадар од екранот (JPEG слика) заедно со структурна снимка од хиерархијата на view-ови и ги прикачува двата — за плеерот во dashboard да може да прикаже репродукција прецизна до пиксел, заедно со временската линија на интеракции. Конфигурирајте го replay за проектот во Контролна табла → Поставки → Снимање на сесии. SDK автоматски ја чита и освежува таа проектна политика, вклучувајќи маскирање, режими на снимање и дозвола за upload преку мобилна мрежа.
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)Кога upload преку мобилна мрежа е исклучен, queued replay чека дозволена мрежа.
Совет
Маскирајте пред upload. Kixo снима pixels, затоа маскирањето се извршува пред нешто да го напушти уредот. Полињата за лозинка и e-mail автоматски се препознаваат и се редигираат; текстот во структурните снимки минува низ PII филтер; а секој view што ќе го означите со setKixoMask(true) се растеризира во непроѕирен правоаголник во кадарот пред да се енкодира JPEG-от — неговите pixels никогаш не го напуштаат уредот. Екраните во Jetpack Compose стандардно се маскираат целосно (повикајте setKixoMask(false) на најнадворешниот ComposeView за да вклучите екран што веќе сте го провериле). Операторите можат да го чистат replay плеерот заедно со временската линија на настани во dashboard.
Собирање податоци
SDK ги снима податоците што се овозможени во вашиот проект, како и настаните и својствата што ги испраќа апликацијата.
Отстранување грешки
Kixo.diagnostics() враќа snapshot само за читање од состојбата на SDK — корисно за скриен debug екран или smoke test. Одговара на прашањето „зошто не ми течат настаните?“ и без 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 stateПрисилно пуштете flush од вашиот test harness — блокира до timeoutMs за едно мрежно кружно патување:
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 / Fragment веднаш создаваат screen_viewevents и структурирани записи screen_visit со метаподатоци за задржување и тек, без дополнително местење. За Jetpack Compose Navigation, повикајте Kixo.screen од LaunchedEffect врзан за рутата — SDK тогаш гледа по еден настан за секоја дестинација, без оглед на бројот на recomposition-и.
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 агенти за кодирање
Јавната површина на SDK е мала и обликувана за code completion — секој метод е на singleton-от Kixo, секој Kotlin пример во овој водич почнува со import io.kixo.sdk.Kixo, а нашиот README вклучува блок „AI agent quick reference“ што алатки како Claude Code, Cursor и Codex можат директно да го вметнат во својот контекст. Ако вашиот agent заглави, канонскиот почеток е:
// 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."Забелешка
Секој дел погоре е напишан имајќи го предвид тој workflow — import-ите секогаш се експлицитни, типовите секогаш се именувани, а singleton-от на SDK никогаш не се alias-ира. Дајте му ја оваа страница на вашиот agent и пуштете го да води.