SDK Android
# Foquz Android SDK
**Версия:** 1.0.0 · **Платформа:** Android · **Язык:** Kotlin · **Package:** `com.foquz.sdk`
---
## Содержание
- [Введение](#введение)
- [Системные требования](#системные-требования)
- [Установка](#установка)
- [Инициализация](#инициализация)
- [Запуск виджетов](#запуск-виджетов)
- [Настройки SDK — FoquzSettings](#настройки-sdk--foquzsettings)
- [Оформление виджетов — FoquzTheme](#оформление-виджетов--foquztheme)
- [FoquzColor](#foquzcolor)
- [FoquzDimen](#foquzdimen)
- [FoquzFont](#foquzfont)
- [Атрибуты таргетинга — FoquzAttributes](#атрибуты-таргетинга--foquzattributes)
- [Обработка событий](#обработка-событий)
- [FoquzOnEventsListener](#foquzoneventslistener)
- [FoquzOnLogListener](#foquzonloglistener)
- [Управление жизненным циклом](#управление-жизненным-циклом)
- [FoquzLifecycleActivity](#foquzlifecycleactivity)
- [FoquzLifecycleRule](#foquzlifecyclerule)
- [Справочник API — класс Foquz](#справочник-api--класс-foquz)
- [ProGuard / R8](#proguard--r8)
- [Примеры](#примеры)
---
## Введение
**Foquz Android SDK** позволяет встраивать интерактивные виджеты обратной связи (NPS-опросы, анкеты, формы оценки) непосредственно в Android-приложение. SDK управляет всеми аспектами работы с виджетами: загрузкой опроса с сервера, определением момента показа, отображением интерфейса и отправкой данных.
**Ключевые возможности:**
- Запуск виджетов по произвольным событиям приложения
- Поддерживаемые типы вопросов: NPS, звёздный рейтинг, варианты ответов, свободный текст, промежуточные блоки
- Гибкая настройка внешнего вида через систему тем
- Передача пользовательских атрибутов для точного таргетинга
- Уведомления о ходе прохождения кампании через callback-интерфейсы
- Автоматическая обработка поворотов экрана
---
## Системные требования
| | |
|---|---|
| Min Android SDK | API 21 (Android 5.0 Lollipop) |
| Compile / Target SDK | API 34 (Android 14) |
| Kotlin | 1.9 и выше |
| Gradle | 8.0 и выше |
| JDK | 17 и выше |
---
## Установка
### Шаг 1. Подключение репозитория
Добавьте Maven-репозиторий Foquz в файл `settings.gradle` (или `settings.gradle.kts`). URL репозитория предоставляется командой Foquz при подключении к платформе.
```groovy
// settings.gradle
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "<FOQUZ_MAVEN_REPO_URL>" }
}
}
```
```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("<FOQUZ_MAVEN_REPO_URL>") }
}
}
```
### Шаг 2. Добавление зависимости
В `build.gradle` (или `build.gradle.kts`) модуля, где используется SDK:
```groovy
// Groovy DSL
dependencies {
implementation 'com.foquz:sdk:1.0.0'
}
```
```kotlin
// Kotlin DSL
dependencies {
implementation("com.foquz:sdk:1.0.0")
}
```
### Шаг 3. Разрешения
Никаких дополнительных настроек в `AndroidManifest.xml` не требуется — необходимые разрешения объявлены в манифесте самой библиотеки. SDK использует разрешение:
```xml
<uses-permission android:name="android.permission.INTERNET" />
```
---
## Инициализация
SDK инициализируется один раз при старте приложения — в классе `Application`, методе `onCreate()`.
```kotlin
import android.app.Application
import com.foquz.sdk.Foquz
import com.foquz.sdk.FoquzSettings
class App : Application() {
override fun onCreate() {
super.onCreate()
Foquz.setup(
context = this,
appId = "ваш-app-id",
settings = FoquzSettings.getDefault().apply {
widgetCode = "ваш-widget-code" // из личного кабинета Foquz
debugEnabled = BuildConfig.DEBUG
}
)
}
}
```
Зарегистрируйте класс в `AndroidManifest.xml`:
```xml
<application android:name=".App" ...>
```
> **Правила инициализации:**
> - `Foquz.setup()` должен вызываться строго в `Application.onCreate()`, и только **один раз**.
> - Повторные вызовы `setup()` не имеют эффекта.
> - До завершения инициализации `Foquz.sdk` возвращает `null`.
> - SDK автоматически отслеживает жизненный цикл Activity и корректно обрабатывает повороты экрана.
### Полная сигнатура setup()
```kotlin
Foquz.setup(
context: Context,
appId: String,
settings: FoquzSettings = FoquzSettings.getDefault(),
campaignListener: FoquzOnEventsListener? = null,
logListener: FoquzOnLogListener? = null
)
```
| Параметр | Тип | Обязательный | Описание |
|---|---|:---:|---|
| `context` | `Context` | ✅ | Контекст приложения (`applicationContext`) |
| `appId` | `String` | ✅ | Идентификатор приложения из личного кабинета Foquz |
| `settings` | `FoquzSettings` | | Настройки SDK; если опущены — применяются значения по умолчанию |
| `campaignListener` | `FoquzOnEventsListener?` | | Подписчик событий кампаний |
| `logListener` | `FoquzOnLogListener?` | | Подписчик отладочного лога SDK |
После инициализации экземпляр SDK доступен через `Foquz.sdk`.
---
## Запуск виджетов
Виджет запускается вызовом `startCampaign()` в любом месте приложения (Activity, Fragment, ViewModel и т.д.):
```kotlin
// Простой запуск по событию
Foquz.sdk?.startCampaign("order_completed")
// Запуск с атрибутами для таргетинга
val attrs = FoquzAttributes()
.addValue("orderId", "ORD-8821")
.addValue("total", 4990.0)
.addValue("itemsCount", 3)
Foquz.sdk?.startCampaign("order_completed", attrs)
```
Для принудительного закрытия показываемого виджета:
```kotlin
Foquz.sdk?.stopCampaign()
```
---
## Настройки SDK — FoquzSettings
`FoquzSettings` — data-класс с настройками поведения SDK. Создайте экземпляр через `FoquzSettings.getDefault()` и переопределите нужные поля через `apply { }`.
```kotlin
val settings = FoquzSettings.getDefault().apply {
widgetCode = "8a64a39a2a1cb187bc9d0b03ddafc9e3"
debugEnabled = BuildConfig.DEBUG
startGlobalDelayTimer = 3600
slideInUiBlocked = true
slideInUiBlackoutOpacity = 45
}
Foquz.setup(this, appId, settings = settings)
```
> **Внимание:** Изменение сетевых параметров (`socketTimeout`, `retryTimeout`, `retryCount`) не рекомендуется без согласования с командой Foquz. Параметр `apiUrlDedicated` принимает только строку специального формата — обратитесь к вашему менеджеру.
### Идентификация виджета
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `widgetCode` | `String` | `""` | **Код виджета из личного кабинета Foquz.** Обязателен для работы. Пример: `"8a64a39a2a1cb187bc9d0b03ddafc9e3"` |
| `apiBaseUrl` | `String` | `"https://widget.foquz.ru/"` | Базовый URL API-сервера Foquz. Не изменяйте без необходимости. |
| `assetsBaseUrl` | `String` | `"https://foquz.ru/"` | Базовый URL сервера опросов. Для тестирования: `"https://demo.foquz.ru/"` |
### Отладка
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `debugEnabled` | `Boolean` | `false` | При `true` SDK выводит подробный лог в Logcat (тег `FoquzSDK`) и вызывает `FoquzOnLogListener.foquzOnLog()` |
### Задержка повторного показа
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `startGlobalDelayTimer` | `Int` | `1800` | Минимальный интервал (сек.) между показами кампаний, у которых в настройках платформы не установлен флаг «показывать всегда» |
### Внешний вид — виджет slideIn
Виджет `slideIn` выезжает снизу экрана поверх контента.
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `slideInUiBlocked` | `Boolean` | `false` | Блокировать взаимодействие с контентом за виджетом |
| `slideInUiBlackoutColor` | `String` | `"#000000"` | Цвет подложки за виджетом (HEX-строка) |
| `slideInUiBlackoutOpacity` | `Int` | `0` | Непрозрачность подложки, 0–100 |
| `slideInUiBlackoutBlur` | `Int` | `0` | Размытие контента за виджетом, 0–100 |
### Внешний вид — виджет popup
Виджет `popup` отображается как диалог поверх всего экрана.
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `popupUiBlackoutColor` | `String` | `"#000000"` | Цвет подложки (HEX-строка) |
| `popupUiBlackoutOpacity` | `Int` | `0` | Непрозрачность подложки, 0–100 |
| `popupUiBlackoutBlur` | `Int` | `0` | Размытие контента за виджетом, 0–100 |
### Сетевые параметры
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `socketTimeout` | `Int` | `25` | Таймаут соединения, сек. ⚠️ не менять |
| `retryTimeout` | `Int` | `300` | Пауза между попытками повтора, сек. ⚠️ не менять |
| `retryCount` | `Int` | `10` | Число повторных попыток ⚠️ не менять |
### Прочее
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| `apiUrlDedicated` | `String?` | `null` | *(Устарело)* Адрес выделенного сервера (специальный формат, предоставляется менеджером). Используйте `apiBaseUrl`. |
| `processName` | `String?` | `null` | Имя процесса, если SDK работает не в основном процессе. Пример: `":worker"` |
| `fieldsEventEnabled` | `Boolean` | `true` | При `true` SDK уведомляет о каждом заполненном поле формы через `foquzOnFieldsEvent()` |
| `defaultLifecycleActivityRule` | `FoquzLifecycleRule` | `ON_START` | Правило жизненного цикла по умолчанию для Activity, не имеющих аннотации `@FoquzLifecycleActivity` |
---
## Оформление виджетов — FoquzTheme
`FoquzTheme` управляет внешним видом всех виджетов: цветами, шрифтами и геометрией элементов. Создайте экземпляр напрямую и задайте нужные свойства:
```kotlin
// Назначить тему
Foquz.sdk?.theme = FoquzTheme().apply {
mainColor = FoquzColor.fromHex("#E63946")
btnBorderRadius = FoquzDimen.fromDp(24)
npsStartColor = FoquzColor.fromHex("#FF6B6B")
npsEndColor = FoquzColor.fromHex("#51CF66")
}
// Точечное изменение параметров у текущей темы
Foquz.sdk?.theme?.apply {
btnBgColor = FoquzColor.fromHex("#1A73E8")
starColor = FoquzColor.fromHex("#FCC419")
}
```
### Параметры темы
#### Цветовая палитра
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `bgColor` | `FoquzColor` | `#FFFFFF` | Фон карточки виджета |
| `iconColor` | `FoquzColor` | `#9CA3AF` | Иконки (кнопка закрытия и т.д.) |
| `text01Color` | `FoquzColor` | `#000000` | Основной текст вопроса и заголовков |
| `text02Color` | `FoquzColor` | `#000000` | Текст вариантов ответов |
| `text03Color` | `FoquzColor` | `#9CA3AF` | Подсказки, метки, второстепенный текст |
| `mainColor` | `FoquzColor` | `#3F65F1` | Акцентный цвет: выделение, прогресс |
| `errorColorPrimary` | `FoquzColor` | `#EF4444` | Цвет сообщений об ошибке |
| `errorColorSecondary` | `FoquzColor` | `#FEE2E2` | Фон блока ошибки |
| `btnBgColor` | `FoquzColor` | `#3F65F1` | Фон основной кнопки |
| `btnBgColorActive` | `FoquzColor` | `#2E55D6` | Фон основной кнопки при нажатии |
| `btnTextColor` | `FoquzColor` | `#FFFFFF` | Текст на кнопке |
| `inputBgColor` | `FoquzColor` | `#FFFFFF` | Фон поля ввода |
| `inputBorderColor` | `FoquzColor` | `#D1D5DB` | Рамка поля ввода |
| `controlBgColor` | `FoquzColor` | `#E5E7EB` | Фон чекбоксов и переключателей |
| `controlBgColorActive` | `FoquzColor` | `#3F65F1` | Фон активного чекбокса / переключателя |
| `controlIconColor` | `FoquzColor` | `#FFFFFF` | Значок внутри активного элемента управления |
#### NPS-шкала
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `npsStartColor` | `FoquzColor` | `#f96261` | Левый (низкий) цвет градиента шкалы NPS |
| `npsEndColor` | `FoquzColor` | `#00c968` | Правый (высокий) цвет градиента шкалы NPS |
#### Звёздный рейтинг
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `starColor` | `FoquzColor` | `#f8cd1c` | Цвет звёзд |
| `starSizeMd` | `FoquzDimen` | `40dp` | Базовый размер звезды для масштаба `"md"`. Масштаб `"sm"` = × 0.65, `"lg"` = × 1.40 |
#### Геометрия
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `formBorderRadius` | `FoquzDimen` | `20dp` | Скругление углов карточки виджета |
| `btnBorderRadius` | `FoquzDimen` | `8dp` | Скругление углов кнопок |
#### Навигационная панель
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `lightNavigationBar` | `Boolean` | `true` | `true` — тёмные иконки панели навигации (для светлого фона) |
#### Типографика
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `fontH1` | `FoquzFont` | 19sp / Regular | Крупный заголовок (текст вопроса) |
| `fontH2` | `FoquzFont` | 16sp / Regular | Заголовок второго уровня |
| `fontP1` | `FoquzFont` | 15sp / Regular | Основной текст вариантов |
| `fontP2` | `FoquzFont` | 13sp / Regular | Мелкий / вспомогательный текст |
| `fontBtn` | `FoquzFont` | 15sp / Bold | Надпись на кнопке |
---
### FoquzColor
Вспомогательный класс для передачи цветовых значений в любом удобном формате.
```kotlin
// HEX-строка (с опциональным альфа-каналом)
val color = FoquzColor.fromHex("#E63946")
val semi = FoquzColor.fromHex("#80E63946") // 50% прозрачности
// Android color int
val color = FoquzColor.fromInt(Color.RED)
val color = FoquzColor.fromInt(ContextCompat.getColor(context, R.color.brand))
```
| Свойство | Тип | Описание |
|---|---|---|
| `hexString` | `String` | Цвет в виде HEX-строки (`"#RRGGBB"` или `"#AARRGGBB"`) |
| `intValue` | `Int` | Цвет как Android ARGB int |
| Фабричный метод | |
|---|---|
| `FoquzColor.fromHex(hex: String)` | |
| `FoquzColor.fromInt(color: Int)` | |
---
### FoquzDimen
Класс для передачи размерных значений: используется в полях скруглений (`FoquzTheme`) и размере шрифта (`FoquzFont`).
```kotlin
val r16 = FoquzDimen.fromDp(16)
val r48 = FoquzDimen.fromPx(48)
```
| Свойство | Тип | Описание |
|---|---|---|
| `dpValue` | `Int` | Размер в density-independent pixels (dp) |
| `pxValue` | `Int` | Размер в физических пикселях (px) |
| Фабричный метод | |
|---|---|
| `FoquzDimen.fromDp(dp: Int)` | |
| `FoquzDimen.fromPx(px: Int)` | |
---
### FoquzFont
Описывает шрифтовое начертание для элементов виджета.
```kotlin
// Шрифт из папки assets/
val brandFont = FoquzFont.fromAsset("fonts/Inter-Regular.ttf")
// Системный шрифт по имени
val systemFont = FoquzFont.fromName("sans-serif-medium")
```
| Свойство | Тип | Описание |
|---|---|---|
| `name` | `String` | Имя шрифта или путь к `.ttf`/`.otf`-файлу в `assets/` |
| `size` | `FoquzDimen` | Кегль шрифта |
| `weight` | `Int` | Насыщенность: 100 (Thin) … 400 (Regular) … 700 (Bold) … 900 (Black) |
| `italic` | `Boolean` | Курсивное начертание |
| `wrap` | `Boolean` | Разрешить перенос текста на новую строку |
| Фабричный метод | |
|---|---|
| `FoquzFont.fromAsset(assetPath: String, sizeDp: Int = 14)` | |
| `FoquzFont.fromName(name: String, sizeDp: Int = 14)` | |
---
## Атрибуты таргетинга — FoquzAttributes
`FoquzAttributes` передаёт контекстные данные о пользователе или текущем экране в момент запуска кампании. На платформе Foquz эти атрибуты используются в правилах показа.
Класс реализует паттерн builder: каждый вызов `addValue()` возвращает тот же объект.
```kotlin
val attrs = FoquzAttributes()
.addValue("screen", "checkout")
.addValue("cartTotal", 4990.0)
.addValue("itemsCount", 2)
.addValue("isPremium", true)
.addValue("lastOrderDate", Date())
Foquz.sdk?.startCampaign("checkout_viewed", attrs)
```
| Перегрузка | Тип значения |
|---|---|
| `addValue(key: String, value: String)` | Текст |
| `addValue(key: String, value: Int)` | Целое число |
| `addValue(key: String, value: Float)` | Дробное число (Float) |
| `addValue(key: String, value: Double)` | Дробное число (Double) |
| `addValue(key: String, value: Boolean)` | Булево значение |
| `addValue(key: String, value: Date)` | Дата и время |
---
## Обработка событий
### FoquzOnEventsListener
Реализуйте этот интерфейс, чтобы получать уведомления о ходе кампании.
```kotlin
interface FoquzOnEventsListener
```
Передайте экземпляр в `Foquz.setup()` или назначьте позже через `Foquz.sdk?.campaignListener`.
#### Методы интерфейса
---
##### `foquzOnReady()`
```kotlin
fun foquzOnReady()
```
SDK завершил инициализацию и готов принимать вызовы `startCampaign()`. Вызывается один раз сразу после `setup()`.
---
##### `foquzOnStartCampaign(campaignId, eventName)`
```kotlin
fun foquzOnStartCampaign(campaignId: Int, eventName: String)
```
Виджет появился на экране. Вызывается в момент начала анимации показа.
| | Тип | Описание |
|---|---|---|
| `campaignId` | `Int` | Числовой идентификатор вопроса / кампании |
| `eventName` | `String` | Событие, инициировавшее показ |
---
##### `foquzOnFinishCampaign(campaignId, eventName)`
```kotlin
fun foquzOnFinishCampaign(campaignId: Int, eventName: String)
```
Пользователь дошёл до последнего экрана и нажал финальную кнопку. Считается успешным завершением.
| | Тип | Описание |
|---|---|---|
| `campaignId` | `Int` | Идентификатор кампании |
| `eventName` | `String` | Событие |
---
##### `foquzOnTerminateCampaign(campaignId, eventName, terminatedPage, totalPages)`
```kotlin
fun foquzOnTerminateCampaign(
campaignId: Int,
eventName: String,
terminatedPage: Int,
totalPages: Int
)
```
Пользователь закрыл виджет, не завершив кампанию.
| | Тип | Описание |
|---|---|---|
| `campaignId` | `Int` | Идентификатор кампании |
| `eventName` | `String` | Событие |
| `terminatedPage` | `Int` | Индекс вопроса, на котором произошло закрытие (нумерация с 0) |
| `totalPages` | `Int` | Общее число вопросов в кампании |
---
##### `foquzOnFieldsEvent(campaignId, eventName, fieldValues)`
```kotlin
fun foquzOnFieldsEvent(
campaignId: Int,
eventName: String,
fieldValues: Map<String, Array<String>>
)
```
Промежуточные данные формы — вызывается при каждом заполнении поля (если `FoquzSettings.fieldsEventEnabled = true`). Позволяет обрабатывать ответы до окончания прохождения.
| | Тип | Описание |
|---|---|---|
| `campaignId` | `Int` | Идентификатор кампании |
| `eventName` | `String` | Событие |
| `fieldValues` | `Map<String, Array<String>>` | Текущие значения полей: ключ — ID поля, значение — массив ответов |
---
##### `foquzNoCampaignToStart(eventName)`
```kotlin
fun foquzNoCampaignToStart(eventName: String)
```
По данному событию не нашлось кампании, доступной для показа (нет виджета на сервере, лимиты показа соблюдены и т.д.).
| | Тип | Описание |
|---|---|---|
| `eventName` | `String` | Событие, для которого кампания не найдена |
---
#### Пример реализации
```kotlin
object MyEventsListener : FoquzOnEventsListener {
override fun foquzOnReady() {
Log.i("Foquz", "SDK инициализирован")
}
override fun foquzOnStartCampaign(campaignId: Int, eventName: String) {
analytics.track("survey_shown", mapOf("id" to campaignId, "event" to eventName))
}
override fun foquzOnFinishCampaign(campaignId: Int, eventName: String) {
analytics.track("survey_completed", mapOf("id" to campaignId))
}
override fun foquzOnTerminateCampaign(
campaignId: Int, eventName: String,
terminatedPage: Int, totalPages: Int
) {
analytics.track("survey_dismissed", mapOf(
"id" to campaignId,
"progress" to "$terminatedPage/$totalPages"
))
}
override fun foquzOnFieldsEvent(
campaignId: Int, eventName: String,
fieldValues: Map<String, Array<String>>
) {
// Обработка промежуточных ответов
}
override fun foquzNoCampaignToStart(eventName: String) {
Log.d("Foquz", "Нет доступных кампаний для события: $eventName")
}
}
```
---
### FoquzOnLogListener
Подключите этот интерфейс, чтобы получать внутренний лог SDK в свою систему логирования. Работает только при `FoquzSettings.debugEnabled = true`.
```kotlin
fun interface FoquzOnLogListener
```
#### Метод интерфейса
##### `foquzOnLog(message)`
```kotlin
fun foquzOnLog(message: String)
```
| | Тип | Описание |
|---|---|---|
| `message` | `String` | Строка лога от SDK |
#### Пример
```kotlin
Foquz.setup(
context = this,
appId = appId,
logListener = FoquzOnLogListener { message ->
Timber.tag("FoquzSDK").d(message)
}
)
```
---
## Управление жизненным циклом
### FoquzLifecycleActivity
Аннотация для классов-наследников `Activity`. Переопределяет поведение SDK на конкретном экране, не затрагивая остальные.
```kotlin
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class FoquzLifecycleActivity(
val lifecycleRule: FoquzLifecycleRule = FoquzLifecycleRule.ON_START
)
```
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
| `lifecycleRule` | `FoquzLifecycleRule` | `ON_START` | Правило обработки жизненного цикла для данной Activity |
**Примеры:**
```kotlin
// Стандартное поведение: явно указано для наглядности
@FoquzLifecycleActivity(FoquzLifecycleRule.ON_START)
class HomeActivity : AppCompatActivity() { ... }
// SDK реагирует на onResume/onPause (актуально для экранов с видео)
@FoquzLifecycleActivity(FoquzLifecycleRule.ON_RESUME)
class PlayerActivity : AppCompatActivity() { ... }
// SDK полностью выключен на этом экране
@FoquzLifecycleActivity(FoquzLifecycleRule.SKIP)
class OnboardingActivity : AppCompatActivity() { ... }
```
---
### FoquzLifecycleRule
Определяет, при каких колбэках жизненного цикла SDK считает Activity «активной» и готов показывать виджеты.
```kotlin
enum class FoquzLifecycleRule
```
| Значение | Описание |
|---|---|
| `ON_START` | SDK активен между `onStart()` и `onStop()`. Используется по умолчанию. |
| `ON_RESUME` | SDK активен между `onResume()` и `onPause()`. Подходит для экранов с частыми переключениями фокуса. |
| `SKIP` | SDK игнорирует данную Activity — виджеты на ней не показываются. |
Для изменения правила по умолчанию для всех Activity, которые не имеют аннотации, используйте `FoquzSettings.defaultLifecycleActivityRule`.
---
## Справочник API — класс Foquz
`Foquz` — основной интерфейс SDK. Экземпляр создаётся через `Foquz.setup()` и доступен как синглтон через `Foquz.sdk`.
### Статические члены
| | |
|---|---|
| `Foquz.setup(...)` | Инициализация SDK — см. раздел [Инициализация](#инициализация) |
| `Foquz.sdk: Foquz?` | Текущий экземпляр SDK; `null` до завершения `setup()` |
### Свойства экземпляра
| Свойство | Тип | Доступ | Описание |
|---|---|---|---|
| `appId` | `String` | read-only | Идентификатор приложения, переданный при инициализации |
| `settings` | `FoquzSettings` | read-only | Активные настройки SDK (изменяйте поля объекта напрямую) |
| `theme` | `FoquzTheme` | read/write | Текущая тема оформления виджетов |
| `properties` | `MutableMap<String, String>` | read-only | Пользовательские свойства для идентификации и таргетинга |
| `campaignListener` | `FoquzOnEventsListener?` | read/write | Подписчик событий кампаний |
| `logListener` | `FoquzOnLogListener?` | read/write | Подписчик отладочного лога |
**Работа с `properties`**
```kotlin
Foquz.sdk?.properties?.apply {
put("clientId", "c_88291")
put("plan", "business")
put("region", "SPb")
}
```
### Методы экземпляра
| Метод | Описание |
|---|---|
| `startCampaign(eventName: String)` | Запустить кампанию по событию |
| `startCampaign(eventName: String, attributes: FoquzAttributes)` | Запустить кампанию с атрибутами |
| `stopCampaign()` | Немедленно скрыть текущий виджет |
---
## ProGuard / R8
При использовании сборок с обфускацией добавьте в `proguard-rules.pro`:
```proguard
# --- Foquz SDK public API ---
-keep class com.foquz.sdk.Foquz { *; }
-keep class com.foquz.sdk.FoquzSettings { *; }
-keep class com.foquz.sdk.FoquzTheme { *; }
-keep class com.foquz.sdk.FoquzAttributes { *; }
-keep class com.foquz.sdk.FoquzColor { *; }
-keep class com.foquz.sdk.FoquzDimen { *; }
-keep class com.foquz.sdk.FoquzFont { *; }
-keep interface com.foquz.sdk.listeners.** { *; }
-keep class com.foquz.sdk.internal.network.model.** { *; }
# --- Gson ---
-keepattributes Signature
-keepattributes *Annotation*
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# --- Retrofit / OkHttp ---
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
# --- Kotlin ---
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings { <fields>; }
```
> При подключении через Gradle конфигурация `consumer-rules.pro` применяется автоматически. Правила выше нужны только при ручной интеграции `.aar`-файла.
---
## Примеры
### Минимальная интеграция
```kotlin
// App.kt
class App : Application() {
override fun onCreate() {
super.onCreate()
Foquz.setup(
context = this,
appId = "ваш-app-id",
settings = FoquzSettings.getDefault().apply {
widgetCode = "ваш-widget-code"
}
)
}
}
```
```kotlin
// MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
Foquz.sdk?.startCampaign("main_screen")
}
}
```
---
### Полная интеграция
```kotlin
class App : Application() {
private val eventsListener = object : FoquzOnEventsListener {
override fun foquzOnReady() =
Log.i("Foquz", "SDK готов")
override fun foquzOnStartCampaign(campaignId: Int, eventName: String) =
Log.d("Foquz", "▶ показ #$campaignId для '$eventName'")
override fun foquzOnFinishCampaign(campaignId: Int, eventName: String) =
Log.d("Foquz", "✓ завершена #$campaignId")
override fun foquzOnTerminateCampaign(
campaignId: Int, eventName: String,
terminatedPage: Int, totalPages: Int
) = Log.d("Foquz", "✗ закрыта на шаге $terminatedPage/$totalPages")
override fun foquzOnFieldsEvent(
campaignId: Int, eventName: String,
fieldValues: Map<String, Array<String>>
) = Log.d("Foquz", "Поля: $fieldValues")
override fun foquzNoCampaignToStart(eventName: String) =
Log.d("Foquz", "Нет кампании для '$eventName'")
}
override fun onCreate() {
super.onCreate()
Foquz.setup(
context = this,
appId = BuildConfig.FOQUZ_APP_ID,
settings = FoquzSettings.getDefault().apply {
widgetCode = BuildConfig.FOQUZ_WIDGET_CODE
debugEnabled = BuildConfig.DEBUG
startGlobalDelayTimer = 1800
slideInUiBlocked = true
slideInUiBlackoutOpacity = 40
slideInUiBlackoutBlur = 15
popupUiBlackoutOpacity = 55
fieldsEventEnabled = true
},
campaignListener = eventsListener,
logListener = FoquzOnLogListener { msg -> Timber.tag("FoquzSDK").v(msg) }
)
}
}
```
---
### Настройка пользователя и темы после логина
```kotlin
class DashboardActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val user = sessionManager.currentUser
// Идентифицируем пользователя
Foquz.sdk?.properties?.apply {
put("clientId", user.id)
put("email", user.email)
put("plan", user.subscription.name)
put("daysSinceRegistration", user.daysSinceReg.toString())
}
// Кастомизируем тему под бренд
Foquz.sdk?.theme = FoquzTheme().apply {
mainColor = FoquzColor.fromHex(user.brandColor ?: "#1A73E8")
btnBgColor = FoquzColor.fromHex(user.brandColor ?: "#1A73E8")
btnBorderRadius = FoquzDimen.fromDp(24)
npsStartColor = FoquzColor.fromHex("#FF6B6B")
npsEndColor = FoquzColor.fromHex("#51CF66")
}
// Запускаем кампанию с атрибутами
Foquz.sdk?.startCampaign(
"dashboard_opened",
FoquzAttributes()
.addValue("clientId", user.id)
.addValue("accountAge", user.daysSinceReg)
.addValue("isPro", user.subscription.isPro)
)
}
}
```
---
### Управление жизненным циклом
```kotlin
// Стандартное поведение (ON_START — по умолчанию)
class HomeActivity : AppCompatActivity() { ... }
// Для экрана с медиа — реагируем на paused/resumed
@FoquzLifecycleActivity(FoquzLifecycleRule.ON_RESUME)
class PlayerActivity : AppCompatActivity() { ... }
// Onboarding — виджеты не показываем
@FoquzLifecycleActivity(FoquzLifecycleRule.SKIP)
class WelcomeActivity : AppCompatActivity() { ... }
```
---
*Foquz Android SDK 1.0.0 · © 2026 Foquz*