Перайсці да дакументацыі

Android SDK

Kixo Android SDK падтрымлівае Kotlin 2.0+ і Java, патрабуе minSdk 24 (Android 7.0) і сабраны супраць compileSdk 35. Хост-праграма па-ранейшаму сама адказвае за свой targetSdk. Адзін выклік Kixo.configure у вашым Application.onCreate аўтаматычна адсочвае экраны, націскі, сесіі, збоі і падзеі жыццёвага цыклу. Для адсочвання push патрэбны мост FCM, апісаны ніжэй. Аўтаадсочванне сеткавых запытаў пакуль не ўваходзіць у бягучы Android-рэліз. SDK таксама падтрымлівае replay сесій, ідэнтычнасць і мэты.

Хуткі старт

Тры файлы. Дадайце Maven-рэпазіторый, дадайце залежнасць, а потым устаўце два радкі ў свой падклас Application.

Патрабаванні да зборкі: compileSdk 35, minSdk 24, Kotlin 2.0+ або Java, і bytecode Java 17.

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 ніжэй. Пераазначайце асобныя сцягі праз KixoConfiguration.Builder(...) толькі пры неабходнасці.

Дадаць у праграму

Maven-рэпазіторый Kixo размешчаны на GitHub Pages. Дадайце яго побач з google() і mavenCentral() у 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")
        }
    }
}

Пасля гэтага аб’явіце залежнасць у модулі праграмы:

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

Парада

android.permission.INTERNET і android.permission.ACCESS_NETWORK_STATE ужо ўключаныя ў маніфест SDK. Дазволы на апавяшчэнні застаюцца пад кантролем вашай праграмы і аб’яўляюцца, толькі калі вы ўключаеце функцыі push.

Шматмодульныя праекты

Канфігурацыя implementation у Gradle — не транзітыўна: калі аб’явіць implementation("io.kixo:kixo-android-sdk:0.1.20") у модулі-бібліятэцы (напрыклад, :core_domain), гэта НЕ зробіць Kixo бачным для :app ці любога іншага спажыўца. Працуюць два варыянты — выберыце адзін.

Pattern A — кожны модуль, які выклікае Kixo, аб’яўляе залежнасць самастойна (рэкамендуецца). захоўвае classpath кожнага модуля мінімальным і пазбягае каскадных перазборак. Выкарыстоўвайце каталог версій (libs.kixo.sdk), каб мяняць версію ў адным месцы.

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
}

Pattern B — рээкспарт праз api(...). Адна дэкларацыя, але ў публічны ABI модуля бібліятэкі цяпер уваходзяць тыпы Kixo — любое павышэнне версіі перазбярэ ўсе залежныя модулі. Выкарыстоўвайце гэта толькі тады, калі бібліятэка паўторна выкарыстоўвае тыпы Kixo ў сваіх публічных сігнатурах (напрыклад, вяртае 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
}

Папярэджанне

Калі падчас кампіляцыі модуля вы бачыце Unresolved reference: Kixo, у гэтага модуля няма ўласнай залежнасці ад SDK — дадайце радок implementation вышэй або выкарыстоўвайце Pattern B.

Ініцыялізацыя

Наладзьце Kixo ў вашым падкласе ApplicationonCreate выконваецца раней за любую activity, таму кожны прагляд экрана, націск і падзея жыццёвага цыклу будуць захоплены з першага кадра. Зарэгіструйце Application у manifest праз 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",
        )
    }
}

Калі патрэбныя дакладныя налады (сцягі auto-track, інтэрвал flush, sampling для replay, уласны хост API), стварыце 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)

Заўвага

Ідэмпатэнтна. Другі выклік configure у тым жа працэсе — no-op з запісам у WARN; SDK пакідае першую канфігурацыю. Падзеі, якія ваша auth-singleton чаргуе да таго, як перад configure спрацуе, буферызуюцца (ліміт 50) і прайграваюцца пасля ініцыялізацыі SDK, таму Kixo.identify(...) можна выклікаць з глабальнага кода яшчэ да завяршэння Application.onCreate.

Адсочванне падзей

Аснову інструментацыі звычайна складаюць тры прымітывы: track для падзей, markGoal для сігналаў канверсіі і addBreadcrumb для кантэксту па-за падзеямі.

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

Парада

Мэты маюць прыярытэт. Пазначаныя мэты выкарыстоўваюцца ў варонках актывацыі Kixo і ў штодзённым cron для выяўлення зменаў — калі аб’ём мэты падае на 70% тыдзень да тыдня, у дашбордзе яна з’явіцца з бейджам Патрэбна праверка. markGoal выкарыстоўвайце для нешматлікіх сапраўды важных момантаў; track — для ўсяго астатняга.

Стандартныя падзеі

Сінтаксічны цукар над Kixo.track для падзей, якія Kixo пазнае па назве, — літаральныя радковыя ключы, якія супастаўляе дэтэктар стандартных падзей на backend. Праверка формы ўласцівасцей на этапе кампіляцыі і адна крыніца праўды для назваў.

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)

Ідэнтыфікаваць карыстальнікаў

Прывязвае наступныя падзеі да стабільнага id карыстальніка і набору traits. Звязванне ананімнага і вядомага карыстальніка адбываецца ў Kixo — падзеі, захопленыя да identify, заднім чыслом будуць аднесены да таго ж карыстальніка.

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

⚠️ Пастка са знакам даляра ў Kotlin. Стандартныя ключы ідэнтычнасці маюць прэфікс $ ($email, $name, $first_name) — і ў радковым літэрале Kotlin вы павінен экранаваць знак даляра як "\$email". Калі напісаць "$email", значэнне зменнай email будзе падстаўлена праз інтэрпаляцыю радка, таму значэнне ціха запішацца як trait карыстальніцкі і не запоўніць слупкі email / name у Audience. Самы просты варыянт — выкарыстаць тыпізаваны overload (SDK 0.1.13+), з якім немагчыма памыліцца: Kixo.setUserProperty(StandardProperty.EMAIL, email).

Пазначыць карыстальніка для сегментацыі

Выкарыстоўвайце setUserProperty са значэннем boolean, каб дадаць карыстальніку простую пазнаку «так/не». Яна захоўваецца паміж запускамi і выкарыстоўваецца ў сегментах, email-кампаніях і запытах у чатах — без дадатковай налады, толькі праз выклік 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",
))

Уласцівасці захоўваюцца праз SharedPreferences паміж запускамi і аўтаматычна дадаюцца да кожнай выходнай падзеі. У чаце можна пісаць нешта кшталту "адправіць вітальны email карыстальнікам, у якіх subscribe = true" — Kixo сам створыць сегмент і падрыхтуе чарнавік шаблону. Ачышчаюцца пры Kixo.reset().

Стандартны каталог уласцівасцей

Зарэзерваваныя ключы ўласцівасцей маюць прэфікс $, таму не канфліктуюць з вашымі ўласнымі traits. Каталог Kixo ахоплівае 37 ключоў у 3 універсальных пакетах (ідэнтычнасць, геа, жыццёвы цыкл) і 5 вертыкальных пакетах B2B (падпіска, e-commerce, медыя, маркетплэйс, лаяльнасць). Задавайце толькі тое, што пасуе вашаму прадукту, — dashboard сам адаптуецца і пакажа толькі запоўненыя пакеты.

Identity

Заўсёды актуальна. Задае слупкі ў загалоўку профілю.

КлючТыпАпісанне
$emailрадокАсноўны email, часта служыць ключом зліцця для звязвання ідэнтычнасці.
$phoneрадокНумар тэлефона ў фармаце E.164.
$nameрадокПоўнае адлюстроўванае імя.
$first_nameрадокІмя.
$last_nameрадокПрозвішча.
$avatar_urlрадокПоўны URL да выявы аватара карыстальніка.

Geo

Геаграфічны кантэкст.

КлючТыпАпісанне
$countryрадокКод краіны паводле ISO 3166.
$cityрадокНазва горада.
$regionрадокШтат або правінцыя.
$timezoneрадокIANA zone накшталт America/Los_Angeles.
$languageрадокIETF tag накшталт en або ru-RU.
$localeрадокПоўны ідэнтыфікатар лакалі.

Жыццёвы цыкл

Калі мы бачылі гэтага карыстальніка.

КлючТыпАпісанне
$createdISO8601Час рэгістрацыі або стварэння акаўнта.
$last_seenISO8601Час апошняга ўзаемадзеяння.

Падпіска

Задавайце, калі ў вашага прадукту ёсць тарыфныя планы.

КлючТыпАпісанне
$planрадокSlug тарыфу — free, pro, enterprise.
$subscription_statusрадокactive / trial / cancelled / past_due.
$trial_endsISO8601Калі заканчваецца бягучы пробны перыяд.
$mrrлікШтомесячны рэгулярны даход у валюце акаўнта.
$subscription_startedISO8601Калі пачалася бягучая падпіска.

Электронная камерцыя

Задавайце, калі прадаяце тавары.

КлючТыпАпісанне
$lifetime_ordersлікКолькасць завершаных заказаў.
$lifetime_revenueлікАгульныя выдаткі.
$aovлікСярэдні чэк.
$last_purchaseISO8601Апошняя паспяховая пакупка.
$first_purchaseISO8601Першая паспяховая пакупка.
$cart_abandoned_countлікАгульная колькасць пакінутых кошыкаў за ўвесь час.

Медыя

Задавайце, калі публікуеце кантэнт.

КлючТыпАпісанне
$content_tierрадокfree / premium / paid.
$subscribed_categoriesCSV string або arrayКатэгорыі, за якімі сочыць карыстальнік.
$watch_time_totalлікАгульны час прагляду ў секундах за ўвесь час.
$last_playedISO8601Апошні запуск прайгравання.

Маркетплэйс

Задавайце, калі ваш прадукт — двухбаковая платформа.

КлючТыпАпісанне
$seller_tierрадокSlug тарыфу на баку прадаўца.
$buyer_tierрадокSlug узроўню на баку пакупніка.
$listings_countлікАктыўныя аб’явы, якімі валодае карыстальнік.
$reviews_countлікВодгукі, якія атрымаў карыстальнік.
$verifiedbooleanСтатус KYC.

Лаяльнасць

Задавайце для праграм узаемадзеяння і ўзнагарод.

КлючТыпАпісанне
$loyalty_pointsлікБягучы баланс даступных для выкарыстання балаў.
$vip_levelрадокSlug узроўню VIP.
$referral_countлікПаспяховыя рэфералы, аднесеныя да гэтага карыстальніка.

Парада

Не бачыце свайго шаблону? Выкарыстоўвайце простыя ключы для custom traits. Яны з’явяцца ў панэлі Custom Traits у аналітычнай панэлі і не будуць засмечваць слупкі профілю. Пяць вертыкальных набораў вышэй — гэта практычныя здагадкі для самых тыповых формаў у B2B; спецыфічная для кліента тэрміналогія (напрыклад, shipping_plan) застаецца без прэфіксаў.

Super-properties

Пары ключ/значэнне на ўзроўні сесіі, якія аўтаматычна дадаюцца да кожнай выходнай падзеі. Гэта не тое самае, што traits identify (яны апісваюць ідэнтычнасць); super-properties апісваюць кантэкст сесіі — актыўны варыянт A/B, build flavor, уключаныя feature flags. Захоўваюцца паміж запускамi; ачышчаюцца пры reset(). Калі ўзнікае канфлікт, значэнні properties у 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-апавяшчэнні

Ёсць два шляхі інтэграцыі. Выбірайце A, калі вы на FCM і хочаце самую кароткую рабочую наладу; выбірайце B, калі ў вас ужо ёсць уласны FirebaseMessagingService, які вы не можаце перабудаваць, або калі вам патрэбны дакладны кантроль над тым, якія дастаўкі FCM бачыць Kixo.

Варыянт A — наследаваць KixoFirebaseMessagingService (аўтаадсочванне)

Стварыце падклас KixoFirebaseMessagingService і выклічце super.onMessageReceived(...) у сваім override — Kixo аўтаматычна адпраўляе push_received (бачны payload) або push_silent (толькі даныя). Базавы клас таксама апрацоўвае рэгістрацыю onNewToken, калі вы яе не override-іце. Рэгістрацыя AndroidManifest.xml не адрозніваецца ад звычайнага FCM service.

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

Заўвага

Kixo кампілюе гэты неабавязковы клас супраць Firebase Messaging, але не дадае Firebase ў вашу праграму транзітыўна. SDK аб’яўляе Firebase як compileOnly; праграма, якая выбірае гэты варыянт, ужо павінна залежаць ад firebase-messaging, як і любы FCM receiver.

Варыянт B — выклікаць ручны API са свайго FCM service

Зарэгіструйце токен FCM у Kixo праз FirebaseMessagingService.onNewToken, а потым яўна лагіруйце кожную дастаўку. Выбірайце гэты шлях, калі хочаце, каб Kixo бачыў толькі частку даставак FCM. На Android дастаўка цяпер падтрымлівае толькі 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 не дае ўніверсальнага lifecycle-hook для адкрыццяў, закрыццяў або кнопак дзеянняў у апавяшчэннях. Перадайце гэтыя сігналы з notification intent-аў або receiver-аў, якія стварае ваша праграма:

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

Прайграванне сесій

Replay дае рэальную візуальную рэканструкцыю таго, што бачыў карыстальнік. Пры кожным захопе SDK кадуе сціснуты кадр экрана (выява JPEG) разам са структурным здымкам іерархіі view і загружае абодва — таму прайгравальнік у дашбордзе можа паказваць піксельна дакладнае прайграванне поруч са шкалой узаемадзеянняў. Наладзьце replay для праекта ў Панэль кіравання → Налады → Паўтор сесіі. SDK аўтаматычна чытае і абнаўляе гэтую праектную палітыку, у тым ліку маскіраванне, рэжымы захопу і дазвол на загрузку праз мабільную сетку.

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)

Калі загрузка праз мабільную сетку адключана, replay у чарзе чакае сеткі, якая дазволена палітыкай.

Парада

Маскіраванне перад загрузкай. Kixo захоплівае пікселі, таму маскіраванне спрацоўвае перад да таго, як што-небудзь пакіне прыладу. Палі з паролямі і e-mail вызначаюцца аўтаматычна і рэдагуюцца; тэкст у структурных здымках праходзіць праз фільтр PII; а любы view, які вы пазначыце праз setKixoMask(true), растэрызуецца ў непразрысты прамавугольнік у кадры перад перад кадаваннем JPEG — яго пікселі ніколі не пакідаюць прыладу. Экраны Jetpack Compose па змаўчанні маскіруюцца цалкам (выклічце setKixoMask(false) на знешнім ComposeView, каб уключыць экран, які вы ўжо праверылі). У дашбордзе аператары пракручваюць прайгравальнік replay паралельна са шкалой часу падзей.

Збор даных

SDK збірае даныя, уключаныя ў вашым праекце, а таксама падзеі і ўласцівасці, якія адпраўляе ваша праграма.

Адладка

Kixo.diagnostics() вяртае здымак стану SDK толькі для чытання — зручна для схаванага debug-экрана або smoke-тэсту. Дазваляе зразумець, «чаму не ідуць падзеі», без 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

Прымусова выканайце flush з вашага тэставага harness-а — выклік блакуецца да timeoutMs на сеткавы round-trip:

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

Маршруты Activity / Fragment адразу ствараюць screen_viewevents і гатовыя структурныя запісы screen_visit з метаданымі пра працягласць і пераходы. Для Jetpack Compose Navigation выклікайце Kixo.screen з LaunchedEffect, прывязаным да route, — тады SDK убачыць адну падзею на кожны пункт прызначэння незалежна ад колькасці recomposition.

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-агенты для напісання кода

Публічная паверхня SDK невялікая і зручная для code completion: усе метады знаходзяцца на singleton Kixo, кожны Kotlin-прыклад у гэтым кіраўніцтве пачынаецца з import io.kixo.sdk.Kixo, а наш README змяшчае блок «AI agent quick reference», які інструменты накшталт Claude Code, Cursor і Codex могуць адразу ўставіць у свой кантэкст. Калі ваш агент затрымаўся, базавы старт такі:

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

Заўвага

Усе раздзелы вышэй напісаныя з улікам такога працоўнага працэсу: imports заўсёды відавочныя, тыпы заўсёды названыя, а singleton SDK ніколі не мае alias. Перадайце гэтую старонку свайму агенту і дайце яму весці працэс.