Конфигурация Android SDK

Инициализируйте SDK один раз при старте приложения. Установка и минимальное приложение; точные сигнатуры собраны в справочнике API.

Инициализация

Основной метод настройки SDK. Вызывается один раз при старте приложения.

Параметр Тип Описание
context Context Контекст приложения.
apiKey String Ваш API key.
section String Идентификатор секции проекта.
gravityEventCallback (TrackingEvent) -> Unit Обязательный callback для действий SDK.
productViewBuilder ProductViewBuilder? Шаблон карточки товара, который приложение передает SDK. Нужен для карточек в дизайне приложения; без него SDK использует демонстрационную карточку.
productFilter ((Slot) -> Boolean)? Фильтр товаров на клиенте.
uiSettings UISettings? UI-настройки встроенных форматов SDK.
logLevel LogLevel Уровень логирования внутреннего SDK-логгера. По умолчанию LogLevel.NONE.

Если GravitySDK.instance вызывается до initialize(...), SDK выбросит исключение GravitySDK has not been initialized.

Логирование SDK

Android SDK поддерживает параметр logLevel в initialize(...). Он управляет только внутренними логами SDK и не влияет на gravityEventCallback, отправку событий или логи приложения.

Логи пишутся через Android Log с тегом GravitySDK.

  • LogLevel.DEBUG включает HTTP debug-логи SDK, включая request/response, и сообщения об ошибках.
  • LogLevel.INFO включает информационные сообщения, например о блокировке показа кампаний, и ошибки.
  • LogLevel.ERROR оставляет только ошибки SDK.
  • LogLevel.NONE отключает локальный вывод SDK. Отправка внутренних ошибок в sdk-sentry.gravityfield.ai/error выполняется отдельно и не отключается уровнем логирования.

По умолчанию используется LogLevel.NONE. При стандартной production-инициализации SDK не пишет в системный лог HTTP-запросы, ответы и API key. Полные request/response логи появляются только при явном LogLevel.DEBUG, поэтому этот режим стоит включать только на время отладки.

Глобальные настройки

Метод задает глобальные настройки, которые применяются ко всем последующим вызовам trackView(...), triggerEvent(...) и getContentBySelector(...).

Пример:

GravitySDK.instance.setOptions(
    options = Options(
        isReturnUserInfo = true,
        isReturnAnalyticsMetadata = true,
    ),
    contentSettings = ContentSettings(
        skusOnly = false,
        fields = listOf("name", "price", "imageUrl"),
    ),
    proxyUrl = "https://my-proxy.example.com/v2",
)

Что настраивается через Options

Поле Значение по умолчанию Назначение
isReturnCounter false Возвращать счетчики в ответе.
isReturnUserInfo false Возвращать информацию о пользователе.
isReturnAnalyticsMetadata false Возвращать дополнительные аналитические метаданные.
isImplicitPageview false Использовать неявный pageview-режим.
isImplicitImpression true Разрешить неявные impression для соответствующих сценариев.

Что настраивается через ContentSettings

Поле Значение по умолчанию Назначение
skusOnly false Возвращать только SKU вместо расширенных товарных данных.
fields null Ограничить список товарных полей в ответе.

Практически это означает следующее:

  • если skusOnly = true, SDK запрашивает только SKU; приложение само догружает товарные данные;
  • если fields задан, SDK запрашивает только указанные товарные поля;
  • если setOptions(...) не вызывается, используются стандартные значения Options() и ContentSettings().

setOptions(...) заменяет настройки целиком; null сбрасывает соответствующий объект к значениям по умолчанию. SDK также передаёт isBuildEngagementUrl = true; через публичный конструктор Options этот флаг не меняется.

proxyUrl задаёт полный базовый URL API, например https://my-proxy.example.com/v2, без завершающего /. SDK добавляет /visit, /event или /choose. Tracking URL из ответа и адрес отправки ошибок этим параметром не заменяются. Без proxyUrl используется https://evs-01.gravityfield.ai/v2.

У текущей реализации Android /choose есть особенности сериализации, в том числе для ContentSettings.

Кастомизация UI

Настройка шрифта

Встроенные UI-компоненты SDK можно стилизовать через UISettings.

val uiSettings = UISettings(fontResId = R.font.my_custom_font)

GravitySDK.initialize(
    context = this,
    apiKey = "YOUR_API_KEY",
    section = "YOUR_SECTION_ID",
    gravityEventCallback = ::handleGravityEvent,
    uiSettings = uiSettings,
)

После этого встроенные текстовые элементы SDK будут использовать указанный шрифт.

Подключение исходного модуля

Если нужно собирать SDK из исходников, скопируйте gravity_sdk, подключите include(":gravity_sdk") и implementation(project(":gravity_sdk")). Дополнительно перенесите version catalog gravity_sdk/gradle/libs.versions.toml как gravitySdk в settings.gradle.kts и задайте SDK_VERSION=1.0.4 в gradle.properties:

dependencyResolutionManagement {
    // Используйте блок repositories вашего проекта.
    versionCatalogs {
        create("gravitySdk") {
            from(files("gravity_sdk/gradle/libs.versions.toml"))
        }
    }
}

Версии Android Gradle Plugin, Kotlin и Compose compiler согласуйте с основным проектом. Простого копирования модуля без его catalog и SDK_VERSION недостаточно.

Обработка обратных вызовов (Callbacks)

Подпишитесь на события SDK через gravityEventCallback в initialize(...). SDK доставляет tracking callbacks через главный поток; навигацию выполняйте в контексте актуального экрана.

Справочник по событиям TrackingEvent

Событие Описание Требует обработки приложением
ContentLoadEvent Контент загружен. Нет
ContentImpressionEvent Контент показан. Нет
ContentVisibleImpressionEvent Контент стал видимым. Нет
ContentCloseEvent Контент закрыт. Нет
CopyEvent Пользователь скопировал значение. Нет
CancelEvent Пользователь отменил действие. Нет
FollowUrlEvent Пользователь нажал на URL. Да
FollowDeeplinkEvent Пользователь нажал на deeplink. Да
RequestPushEvent Пользователь инициировал сценарий push-permission. Опционально
ProductImpressionEvent Карточка товара стала видимой. Нет

Пример обработки:

private fun handleGravityEvent(event: TrackingEvent) {
    when (event) {
        is FollowUrlEvent -> {
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(event.url))
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        }
        is FollowDeeplinkEvent -> {
            // Выполните навигацию по deeplink
        }
        is RequestPushEvent -> {
            // При необходимости обработайте событие в аналитике
        }
        else -> Unit
    }
}

Передача статуса Push-уведомлений

Если таргетинг кампаний зависит от статуса push-разрешения, передавайте его в SDK.

setNotificationPermissionStatus()

Допустимые значения:

  • NotificationPermissionStatus.GRANTED
  • NotificationPermissionStatus.DENIED
  • NotificationPermissionStatus.UNKNOWN

Пример:

import androidx.core.app.NotificationManagerCompat

val areNotificationsEnabled =
    NotificationManagerCompat.from(context).areNotificationsEnabled()

val status = if (areNotificationsEnabled) {
    NotificationPermissionStatus.GRANTED
} else {
    NotificationPermissionStatus.DENIED
}

GravitySDK.instance.setNotificationPermissionStatus(status)

SDK добавляет это значение в device.permission последующих запросов. Для базовой интеграции этот шаг не обязателен, но он необходим, если push-статус участвует в таргетинге.

Блокировка показа in-app кампаний

Используйте presentation lock, когда приложение показывает собственную модалку, bottom sheet, onboarding или другой приоритетный слой интерфейса, который не должен перекрываться кампанией Gravity.

private fun showCheckoutBottomSheet() {
    GravitySDK.instance.lockPresentation()

    CheckoutBottomSheet(
        onDismiss = {
            GravitySDK.instance.unlockPresentation()
        }
    ).show(supportFragmentManager, "checkout")
}

Пока блокировка активна, SDK может загрузить контент, но не будет показывать новую in-app кампанию поверх текущего интерфейса. Уже открытый Gravity-контент этим вызовом не закрывается.

Если приложению нужно отслеживать состояние блокировки, подпишитесь на изменения:

GravitySDK.instance.setPresentationLockListener { locked ->
    // Обновите состояние приложения, если это нужно вашему UI
}

Это один Boolean-флаг, счётчика вложенных блокировок нет. Повторный lock не требует дополнительного unlock. Пропущенная кампания не ставится в очередь и не появится автоматически после разблокировки. Ручная загрузка и inline-компоненты не блокируются. В Android 1.0.4 переход OPEN_STEP вызывает показ напрямую и также не проверяет presentation lock.

Listener вызывается синхронно на потоке вызывающего кода при lock/unlock; при подписке текущее состояние не отправляется. Для снятия подписки передайте null. При dispose() listener очищается.