diff --git a/.yfm b/.yfm index a6d83eb4..4ac2dc1a 100644 --- a/.yfm +++ b/.yfm @@ -2,7 +2,8 @@ allowHTML: true langs: ['en','ru'] interface: - toc-header: false + toc: true + feedback: false favicon-src: https://storage.yandexcloud.net/diplodoc-www-assets/favicon/favicon.ico resources: diff --git a/ru/_includes/feedback-button.md b/ru/_includes/feedback-button.md new file mode 100644 index 00000000..e42f5625 --- /dev/null +++ b/ru/_includes/feedback-button.md @@ -0,0 +1,26 @@ + diff --git a/ru/about.md b/ru/about.md index 3d040455..6ed8f93f 100644 --- a/ru/about.md +++ b/ru/about.md @@ -1,26 +1,49 @@ -# О Diplodoc +--- +title: Заголовок 1 -Добро пожаловать на платформу документирования Diplodoc — решение, созданное для тех, кто стремится эффективно управлять и публиковать документацию с использованием подхода «docs as code». +feedback: true +toc: false +favicon-src: https://cs11.pikabu.ru/post_img/big/2018/11/12/6/1542010753153392364.png +qqq: wtf +--- -Diplodoc предоставляет два варианта использования (оба из которых абсолютно бесплатны): -{% list tabs %} +# ECommerce -- Серверная версия +При совершении покупок в приложении пользователи выполняют различные действия (ECommerce-события). Например: - Серверная версия Diplodoc обеспечивает простоту и удобство использования платформы без необходимости организации собственного хостинга. В этом варианте вся обработка и рендеринг контента осуществляется на наших ресурсах. +- открытие страницы; +- просмотр карточки и страницы товара; +- добавление и удаление товара из корзины; +- начало и завершение оформления покупки. - Вы просто работаете с Markdown-файлами на GitHub, и платформа автоматически генерирует из них документацию на домене [diplodoc.com](https://diplodoc.com/). +AppMetrica позволяет собирать информацию о таких действиях и отслеживать статистику в веб-интерфейсе, в отчете. - Одним из преимуществ серверной версии является возможность проксирования с вашего собственного домена, что позволяет сохранить брендовый стиль и профессиональный вид документационного портала. +Чтобы собирать статистику по ECommerce-событиям, настройте отправку в приложении. Подробнее в разделе. -- Cтатическая документация +## Настройка группировок и метрик {#metrics} - Для пользователей, предпочитающих полный контроль над инфраструктурой, Diplodoc предлагает вариант использования через интерфейс командной строки (CLI). +Отчет «Анализ покупок» можно настроить под ваши задачи с помощью группировок и метрик. Подробнее о доступных группировках и метриках в разделе [Отчет Ecommerce]. - В этом сценарии вы можете использовать наш CLI для генерации статических HTML-страниц из вашего контента, написанного в Markdown. +Например, с помощью отчета можно оценить: +- количество просмотров карточки или страницы товара; +- количество добавлений в корзину; +- количество покупок; +- объём выручки, возвратов и продаж со скидкой; +- географию покупок с помощью группировки по городам. - Этот подход позволяет размещать собранные файлы на любых собственных хостинговых платформах, обеспечивая максимальную гибкость и независимость. Это идеальный вариант для команд, желающих интегрировать процесс создания документации в свои CI/CD пайплайны. +## Отладка отправки ECommerce-событий {#debug} -{% endlist %} +В AppMetrica нет возможности сегментировать ECommerce-события на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые события будут попадать в общую статистику. Поэтому, чтобы отладить отправку ECommerce-событий, используйте отправку статистики на дополнительный API key с помощью репортера. Подробнее см. примеры в разделе. +## Отправка ECommerce-событий {#send-ecommerce} + +Примеры отправки ECommerce-события на платформах: + +- [Android](features.md#send-ecommerce) +- [iOS](features.md#send-ecommerce) +- [Flutter](features.md#send-ecommerce) +- [React Native](features.md#send-ecommerce) +- [Unity](features.md#send-ecommerce) + +{% include notitle [feedback](./_includes/feedback-button.md) %} diff --git a/ru/features.md b/ru/features.md index 9afa6480..281cd330 100644 --- a/ru/features.md +++ b/ru/features.md @@ -1,33 +1,2627 @@ -# Функциональные возможности +--- +title: Заголовок 2 +description: Описание -## Простота использования +interface: + feedback: true + toc-header: false + favicon-src: https://cs11.pikabu.ru/post_img/big/2018/11/12/6/1542010753153392364.png + qqq: wtf -Управляйте документами так же, как исходным кодом: в привычной среде с минимальными усилиями на развертывание и обслуживание. +resources: + test: test -## Расширенный Markdown +docs-viewer: + project-name: qqq + langs: ['zh','ru'] +--- -Используйте [улучшенный Markdown](syntax/index.md) с необходимыми компонентами для документации, такими как кодовые блоки, изображения, диаграммы и многое другое. -## Комбинирование ручной и генерируемой документации +# Примеры использования методов -Поддерживается генерация из [OpenAPI-спецификаций](guides/openapi.md), а также автогенерация из Swift и Objective-C. +## Инициализация библиотеки с расширенной конфигурацией {#initialize} -## Локализация +С помощью расширенной конфигурации можно включить/отключить, установить тайм-аут сессии, передать параметры для [отслеживания предустановленных приложений] и т. д. -Платформа нативно поддерживает [извлечение текста](tools/docs/translate.md) для различных систем перевода, таких как SmartCAT, Weblate, YaCAT и Яндекс Переводчик. +Настройки расширенной конфигурации применяются с момента инициализации библиотеки. -## Конструктор страниц +Чтобы инициализировать библиотеку с расширенной стартовой конфигурацией, создайте объект класса `AppMetricaConfig` с необходимыми настройками и активируйте библиотеку с помощью метода `AppMetrica.activate(Context context, AppMetricaConfig config)`. -Платформа нативно поддерживает [Page Constructor](https://github.com/gravity-ui/page-constructor) — тип страниц, позволяющих пользователям создавать страницы-лендинги с каруселями, фонами, плавно анимированными карточками и различными другими блоками. +{% list tabs group=instructions %} -## Поддержка Right-to-Left +- Kotlin -Diplodoc предоставляет возможность поддержки режима Right-to-Left (RTL), обеспечивая беспрепятственный доступ и читаемость для таких языков, как арабский и иврит. + ```kotlin translate=no + class YourApplication : Application() { + override fun onCreate() { + super.onCreate() + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting up the configuration. For example, to enable logging. + .withLogs() + // ... + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + // Automatic tracking of user activity. + AppMetrica.enableActivityAutoTracking(this) + } + } + ``` -## Встроенная функция поиска +- Java -Наиболее типичный сценарий использования [поиска документов](project/lunr.md) на платформе, без дополнительных затрат или усилий по поддержке. + ```java translate=no + public class YourApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting up the configuration. For example, to enable logging. + .withLogs() + // ... + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + // Automatic tracking of user activity. + AppMetrica.enableActivityAutoTracking(this); + } + } + ``` -## Визуальные возможности +{% endlist %} -Платформа позволяет быстро создавать понятные формулы, красивые диаграммы и разводящие страницы, благодаря наличию [Mermaid](tools/mermaid.md), PlantUML, LaTeX. \ No newline at end of file +Чтобы настроить библиотеку в процессе работы приложения, используйте методы класса `AppMetrica`. + +## Отправка статистики на дополнительный API key {#reporter-different-apikey} + +Отправка данных на дополнительный API key позволяет собирать для каждого API key свою статистику. Это можно использовать для управления доступом к информации. Например, чтобы предоставить доступ к статистике для аналитиков, можно продублировать отправку маркетинговых данных на дополнительный API key и предоставить им доступ к этой статистике. Так у них будет доступ только к той информации, которая им необходима. + +Для отправки данных на дополнительный API key необходимо использовать репортеры. С помощью них можно отправлять события, сообщения об ошибках, профили и информацию о покупках в приложении. Репортеры могут работать без инициализации AppMetrica SDK. + +### Шаг 1. (Опционально) Инициализируйте репортер с расширенной конфигурацией {#reporter-different-apikey-initialize} + +Чтобы инициализировать репортер с расширенной конфигурацией, создайте объект класса `ReporterConfig` с необходимыми настройками и активируйте репортер с помощью метода `AppMetrica.activateReporter(Context context, ReporterConfig config)`. Конфигурация применяется для репортера с указанным API key. Для каждого дополнительного API key можно настроить свою конфигурацию. + +{% note alert %} + + Инициализацию репортера с расширенной конфигурацией необходимо проводить до первого обращения к репортеру. Иначе репортер будет инициализирован без конфигурации. + +{% endnote %} + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating extended configuration of the reporter. + // To create it, pass a ANOTHER_API_KEY that is different from the app's API_KEY. + val reporterConfig = ReporterConfig.newConfigBuilder(ANOTHER_API_KEY) + // Setting up the configuration. For example, to enable logging. + .withLogs() + // ... + .build() + // Initializing a reporter. + AppMetrica.activateReporter(applicationContext, reporterConfig) + ``` + +- Java + + ```java translate=no + // Creating extended configuration of the reporter. + // To create it, pass a ANOTHER_API_KEY that is different from the app's API_KEY. + ReporterConfig reporterConfig = ReporterConfig.newConfigBuilder(ANOTHER_API_KEY) + // Setting up the configuration. For example, to enable logging. + .withLogs() + // ... + .build(); + // Initializing a reporter. + AppMetrica.activateReporter(getApplicationContext(), reporterConfig); + ``` + +{% endlist %} + +### Шаг 2. Настройте отправку данных с помощью репортера {#reporter-different-apikey-send} + +Для отправки данных с помощью репортера, необходимо получить объект, который реализует интерфейс `IReporter` с помощью метода `AppMetrica.getReporter(Context context, String apiKey)` и использовать методы интерфейса для отправки отчетов. Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key. + +Пример отправки события: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.getReporter(applicationContext, ANOTHER_API_KEY).reportEvent("Updates installed") + ``` + +- Java + + ```java translate=no + AppMetrica.getReporter(getApplicationContext(), ANOTHER_API_KEY).reportEvent("Updates installed"); + ``` + +{% endlist %} + +Для корректного отслеживания сессий взаимодействия пользователя с приложением настройте отправку событий о начале и приостановке сессии для каждого репортера. Для этого используйте методы `resumeSession()` и `pauseSession()` интерфейса `IReporter` в реализации `onResume()` и `onPause()` ваших Activity: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + public class YourActivity : Activity() { + override fun onResume() { + super.onResume() + AppMetrica.getReporter(applicationContext, ANOTHER_API_KEY).resumeSession() + } + + override fun onPause() { + AppMetrica.getReporter(applicationContext, ANOTHER_API_KEY).pauseSession() + super.onPause() + } + } + ``` + +- Java + + ```java translate=no + public class YourActivity extends Activity { + @Override + protected void onResume() { + super.onResume(); + AppMetrica.getReporter(getApplicationContext(), ANOTHER_API_KEY).resumeSession(); + } + + @Override + protected void onPause() { + AppMetrica.getReporter(getApplicationContext(), ANOTHER_API_KEY).pauseSession(); + super.onPause(); + } + } + ``` + +{% endlist %} + +## Отслеживание аварийных остановок приложения {#set-report-crash} + +Отчеты об аварийных остановках приложения отправляются по умолчанию. + +Чтобы отключить автоматическое отслеживание, инициализируйте библиотеку с конфигурацией, в которой отправка информации об аварийных остановках приложения отключена. Для этого передайте значение `false` в метод `withCrashReporting(boolean enabled)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetrica.newConfigBuilder(API_KEY) + // Disabling the data sending about the app crashes. + .withCrashReporting(false) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling the data sending about the app crashes. + .withCrashReporting(false) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +Если автоматическое отслеживание отключено, вы можете [отправлять информацию об аварийных остановках вручную](#report-unhandled). + +## Отслеживание аварийных остановок приложения вручную {#report-unhandled} + +Отчеты об аварийных остановках приложения отправляются по умолчанию. Чтобы избежать дублирования событий при ручной отправке, необходимо отключить [автоматическое отслеживание аварийных остановок](#set-peropt-crash). + +Чтобы отправлять информацию об аварийных остановках приложения вручную, используйте метод `AppMetrica.reportUnhandledException(Throwable exception)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val previousUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler() + // Creating a new handler. + val uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { thread, exception -> + try { + // Sending a message about an app crash to the AppMetrica server. + AppMetrica.reportUnhandledException(exception) + } finally { + // Sending a message about an app crash to the system handler. + previousUncaughtExceptionHandler?.uncaughtException(thread, exception) + } + } + // Setting the default handler. + Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler) + ``` + +- Java + + ```java translate=no + final Thread.UncaughtExceptionHandler previousUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); + // Creating a new handler. + Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable exception) { + try { + // Sending a message about an app crash to the AppMetrica server. + AppMetrica.reportUnhandledException(exception); + } finally { + // Sending a message about an app crash to the system handler. + if (previousUncaughtExceptionHandler != null) { + previousUncaughtExceptionHandler.uncaughtException(thread, exception); + } + } + } + }; + // Setting the default handler. + Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler); + ``` + +{% endlist %} + +## Отслеживание нативных аварийных остановок приложения {#native-crashes} + +Отчеты о нативных аварийных остановках приложения отправляются автоматически, если SO-файлы библиотеки добавлены в проект. +По умолчанию SO-файлы отсутствуют. +Чтобы добавить их, настройте следующим образом: + +{% list tabs %} + +- build.gradle.kts + + ```kotlin translate=no + appmetrica { + ... + ndk { + enable = { applicationVariant -> true } + } + } + ``` + +- build.gradle + + ```groovy translate=no + appmetrica { + ... + ndk { + enable = { applicationVariant -> true } + } + } + ``` + +{% endlist %} + +Плагин автоматически подключит необходимые зависимости. +Подключаемая плагином бибилотека содержит so-файлы для всех платформ (arm, armv7, mips, x86). +Используйте [abi splits](https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split) для исключения неиспользуемых so-файлов. + +{% cut "Если вы не используете Gradle" %} + +[Загрузите](https://repo1.maven.org/maven2/io/appmetrica/analytics/analytics-ndk-crashes/{{ io-appmetrica-analytics-analytics-ndk-crashes }}/analytics-ndk-crashes-{{ io-appmetrica-analytics-analytics-ndk-crashes }}.aar) и добавьте библиотеку в проект. + +{% endcut %} + +Чтобы отключить автоматическое отслеживание, инициализируйте библиотеку с конфигурацией, в которой отправка информации о нативных аварийных остановках приложения отключена. +Для этого передайте значение `false` в метод `withNativeCrashReporting(boolean enabled)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling the data sending about the native app crashes. + .withNativeCrashReporting(false) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling the data sending about the native app crashes. + .withNativeCrashReporting(false) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +[Подробнее о нативном коде](https://developer.android.com/tools/sdk/ndk/index.html#Using). + +## Отправка рекламных идентификаторов библиотекой {#track-adv-identifiers} + +{% note info %} + +Отправка рекламных идентификаторов с событиями по умолчанию включена. + +{% endnote %} + +Если вам необходимо отключить сбор рекламных идентификаторов по какой-либо причине, например, вы ожидаете согласие пользователя, отключите отправку на этапе инициализации библиотеки. Для этого передайте значение `false` в метод `withAdvIdentifiersTracking (boolean enabled)` при создании конфигурации. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling advertising identifiers tracking + .withAdvIdentifiersTracking(false) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling advertising identifiers tracking + .withAdvIdentifiersTracking(false) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +После получения согласия пользователя рекомендуется включить сбор рекламных идентификаторов в процессе работы. Для этого передайте значение `true` в метод `AppMetrica.setAdvIdentifiersTracking(boolean enabled)`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Enabling advertising identifiers tracking + AppMetrica.setAdvIdentifiersTracking(true) + ``` + +- Java + + ```java translate=no + // Enabling advertising identifiers tracking + AppMetrica.setAdvIdentifiersTracking(true); + ``` + +{% endlist %} + +## Отправка местоположения устройства библиотекой {#track-location} + +{% note info "" %} + +Отправка местоположения устройства по умолчанию отключена. + +Начиная с версии 5.0.0 AppMetrica SDK по умолчанию инициализируется с отключенной опцией `locationTracking`. + +{% endnote %} + +Чтобы включить отправку, инициализируйте библиотеку с конфигурацией, в которой отправка информации о местоположении устройства включена. Для этого передайте значение `true` в метод `withLocationTracking(boolean enabled)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Enabling the data sending about the device location. + .withLocationTracking(true) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Enabling the data sending about the device location. + .withLocationTracking(true) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +Чтобы включить отправку в процессе работы приложения, используйте метод `AppMetrica.setLocationTracking(boolean enabled)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.setLocationTracking(true) + ``` + +- Java + + ```java translate=no + AppMetrica.setLocationTracking(true); + ``` + +{% endlist %} + +Для более точного определения местоположения добавьте в файл AndroidManifest.xml одно из следующих разрешений: + +- [android.permission.ACCESS_COARSE_LOCATION](https://developer.android.com/reference/android/Manifest.permission.html#ACCESS_COARSE_LOCATION) — для приблизительного определения. +- [android.permission.ACCESS_FINE_LOCATION](https://developer.android.com/reference/android/Manifest.permission.html#ACCESS_FINE_LOCATION) — для точного определения. + +Например: + +```xml translate=no + + + ... + +``` + +## Установка местоположения вручную {#location-manual} + +Перед отправкой собственной информации о местоположении устройства убедитесь, что отправка отчетов была включена. + +Библиотека определяет местоположение устройства самостоятельно. Чтобы отправить собственную информацию о местоположении устройства, передайте объект класса [android.location.Location](https://developer.android.com/reference/android/location/Location) в метод `AppMetrica.setLocation(Location location)`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Determining the location. + val currentLocation = ... + // Setting your own location information of the device. + AppMetrica.setLocation(currentLocation) + ``` + +- Java + + ```java translate=no + // Determining the location. + Location currentLocation = ...; + // Setting your own location information of the device. + AppMetrica.setLocation(currentLocation); + ``` + +{% endlist %} + +Чтобы отправить собственную информацию о местоположении устройства с помощью стартовой конфигурации, передайте объект `android.location.Location` в метод `withLocation(Location location)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Determining the location. + val currentLocation = ... + + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Set your own location information of the device. + .withLocation(currentLocation) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Determining the location. + Location currentLocation = ...; + + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Set your own location information of the device. + .withLocation(currentLocation) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +Чтобы возобновить определение местоположения библиотекой, передайте в метод `AppMetrica.setLocation(Location location)` значение `null` и настройте [отправку местоположения устройства](#track-location). + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.setLocation(null) + ``` + +- Java + + ```java translate=no + AppMetrica.setLocation(null); + ``` + +{% endlist %} + +## Отправка собственного события {#report-event} + +Чтобы отправить собственное событие без вложенных параметров, передайте короткое название или описание события в метод `AppMetrica.reportEvent(String eventName)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.reportEvent("Updates installed") + ``` + +- Java + + ```java translate=no + AppMetrica.reportEvent("Updates installed"); + ``` + +{% endlist %} + +## Отправка собственного события с вложенными параметрами {#report-event-params} + +AppMetrica SDK позволяет отправлять собственные события с вложенными параметрами, которые могут быть заданы в формате JSON или в виде набора атрибутов (Map). + +**JSON** + +Чтобы передать вложенные параметры события в формате JSON, используйте метод `AppMetrica.reportEvent(String eventName, String jsonValue)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val eventParameters = """{"name":"Alice", "age":"18"}""" + + AppMetrica.reportEvent("New person", eventParameters) + ``` + +- Java + + ```java translate=no + String eventParameters = "{\"name\":\"Alice\", \"age\":\"18\"}"; + + AppMetrica.reportEvent("New person", eventParameters); + ``` + +{% endlist %} + +**Map** + +Чтобы передать вложенные параметры события в виде набора атрибутов (Map), используйте метод `AppMetrica.reportEvent(String eventName, Map attributes)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val eventParameters = mapOf("name" to "Alice", "age" to 18) + + AppMetrica.reportEvent("New person", eventParameters) + ``` + +- Java + + ```java translate=no + Map eventParameters = new HashMap(); + eventParameters.put("name", "Alice"); + eventParameters.put("age", 18); + + AppMetrica.reportEvent("New person", eventParameters); + ``` + +{% endlist %} + + +Веб-интерфейс AppMetrica отображает до пяти уровней вложенности события. Если событие содержит шесть уровней и более, в отчете отобразятся пять верхних. С помощью можно выгрузить до десяти уровней. + +Подробнее о событиях в разделе. + +## Отправка события из JavaScript-кода WebView {#js-event} + +AppMetrica SDK позволяет отправлять клиентские события из JavaScript-кода. Инициализируйте отправку вызовом метода `initWebViewReporting`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val webView = findViewById(R.id.myWebView) + // do your initialization here + webView.settings.javaScriptEnabled = true + AppMetrica.initWebViewReporting(webView) + webView.loadUrl(myURL) + ``` + +- Java + + ```java translate=no + WebView webView = (WebView) findViewById(R.id.myWebView); + // do your initialization here + webView.getSettings().setJavaScriptEnabled(true); + AppMetrica.initWebViewReporting(webView); + webView.loadUrl(myURL); + ``` + +{% endlist %} + +Вызывайте метод `initWebViewReporting` после вызова метода `setJavaScriptEnabled` и до вызова loadUrl. + +Для отправки события из JavaScript-кода используйте метод `reportEvent(name, value)` интерфейса AppMetrica: + +**Javascript** + + ```javascript translate=no + function buttonClicked() { + AppMetrica.reportEvent('Button clicked!', '{}'); + } + ``` + +Аргументы метода `reportEvent`: + +- `name` — строка. Не может быть null или пустым. +- `value` — JSON-строка. Может быть null. + +## Отправка собственного сообщения об ошибке {#send-report-error} + +Чтобы отправить собственное сообщение об ошибке, используйте методы: + +- `AppMetrica.reportError(String message, Throwable error)` +- `AppMetrica.reportError(String groupIdentifier, String message)` +- `AppMetrica.reportError(String groupIdentifier, String message, Throwable error)` + +{% cut "Пример c groupIdentifier" %} + +Если ошибки отправляются с помощью методов c groupIdentifier, они группируются по идентификатору. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + try { + "00xffWr0ng".toInt() + } catch (error: Throwable) { + AppMetrica.reportError("Your ID", "Error while parsing some integer number", error) + } + ``` + + - Java + + ```java translate=no + try { + Integer.valueOf("00xffWr0ng"); + } catch (Throwable error) { + AppMetrica.reportError("Your ID", "Error while parsing some integer number", error); + } + ``` + + {% endlist %} + +Не используйте переменные значения в качестве идентификатора для группировки. Иначе количество групп будет увеличиваться и их будет сложно анализировать. + +![](https://yastatic.net/s3/doc-binary/src/dev/appmetrica/{{locale}}/images/common/id-group-android.png){style="border: solid 1px #cccccc; max-width: 800px;"} + +{% endcut %} + +{% cut "Пример c message" %} + +Если ошибки отправляются с помощью метода `AppMetrica.reportError(String message, Throwable error)`, они группируются по [stack trace](https://en.wikipedia.org/wiki/Stack_trace). + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + try { + "00xffWr0ng".toInt() + } catch (error: Throwable) { + AppMetrica.reportError("Error while parsing some integer number", error) + } + ``` + + - Java + + ```java translate=no + try { + Integer.valueOf("00xffWr0ng"); + } catch (Throwable error) { + AppMetrica.reportError("Error while parsing some integer number", error); + } + ``` + + {% endlist %} + +![](https://yastatic.net/s3/doc-binary/src/dev/appmetrica/{{locale}}/images/common/msg-group-android.png){style="border: solid 1px #cccccc; max-width: 800px;"} + +{% endcut %} + +## Отправка событий из буфера {#send-events-buffer} + +AppMetrica SDK не отправляет событие сразу после того, как оно произошло. Библиотека хранит данные о событиях в буфере. Метод `sendEventsBuffer` инициирует отправку данных из буфера и очищает его. Используйте этот метод для принудительной отправки сохраненных событий после прохождения важных сценариев пользователя. + + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.sendEventsBuffer() + ``` + +- Java + + ```java translate=no + AppMetrica.sendEventsBuffer(); + ``` + +{% endlist %} + +{% note alert "" %} + +Частое использование метода может привести к повышению энергопотребления и расходу интернет-трафика. + +{% endnote %} + +## Отправка ProfileId {#send-profile-id} + +Если идентификатор пользовательского профиля известен до инициализации AppMetrica SDK, передавайте его до инициализации (`setUserProfileID`) или во время инициализации с расширенной конфигурацией (`withUserProfileID`). + +В противном случае будет создан пользовательский профиль с идентификатором `appmetrica_device_id`. + +{% note warning "" %} + +Если отправка `ProfileId` не настроена, не отображаются в веб-интерфейсе. + +{% endnote %} + +В любой момент можно обновить `ProfileId` с помощью вызова `setUserProfileID`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.setUserProfileID("id") + ``` + +- Java + + ```java translate=no + AppMetrica.setUserProfileID("id"); + ``` + + {% endlist %} + +## Отправка атрибутов профиля {#send-attribute-profile} + +Чтобы отправить атрибуты профиля, передайте в объект `UserProfile` необходимые атрибуты и отправьте этот объект с помощью метода `AppMetrica.reportUserProfile(UserProfile profile)`. Атрибуты профиля создаются с помощью методов класса `Attribute`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating the UserProfile instance. + val userProfile = UserProfile.newBuilder() + // Updating predefined attributes. + .apply(Attribute.name().withValue("John")) + .apply(Attribute.gender().withValue(GenderAttribute.Gender.MALE)) + .apply(Attribute.birthDate().withAge(24)) + .apply(Attribute.notificationsEnabled().withValue(false)) + // Updating custom attributes. + .apply(Attribute.customString("string_attribute").withValue("string")) + .apply(Attribute.customNumber("number_attribute").withValue(55.0)) + .apply(Attribute.customCounter("counter_attribute").withDelta(1.0)) + .build() + // Setting the ProfileID using the method of the AppMetrica class. + AppMetrica.setUserProfileID("id") + + // Sending the UserProfile instance. + AppMetrica.reportUserProfile(userProfile) + ``` + +- Java + + ```java translate=no + // Creating the UserProfile instance. + UserProfile userProfile = UserProfile.newBuilder() + // Updating predefined attributes. + .apply(Attribute.name().withValue("John")) + .apply(Attribute.gender().withValue(GenderAttribute.Gender.MALE)) + .apply(Attribute.birthDate().withAge(24)) + .apply(Attribute.notificationsEnabled().withValue(false)) + // Updating custom attributes. + .apply(Attribute.customString("string_attribute").withValue("string")) + .apply(Attribute.customNumber("number_attribute").withValue(55)) + .apply(Attribute.customCounter("counter_attribute").withDelta(1)) + .build(); + // Setting the ProfileID using the method of the AppMetrica class. + AppMetrica.setUserProfileID("id"); + + // Sending the UserProfile instance. + AppMetrica.reportUserProfile(userProfile); + ``` + +{% endlist %} + +## Отправка ECommerce-событий {#send-ecommerce} + +В AppMetrica нет возможности сегментировать ECommerce-события на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые события будут попадать в общую статистику. Поэтому, чтобы отладить отправку ECommerce-событий, используйте отправку статистики на дополнительный API key с помощью репортера. + +### Шаг 1. Настройте отправку ECommerce-событий на тестовый API key {#send-ecommerce-test-key} + +Для различных действий пользователя есть соответствующие типы ECommerce-событий. Чтобы создать конкретный тип события, используйте нужный метод класса `ECommerceEvent`. + +Ниже приведены примеры отправки конкретных типов событий: + +{% cut "Открытие страницы" %} + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val payload = mapOf( + "configuration" to "landscape", + "full_screen" to "true", + ) + // Creating a screen object. + val screen = ECommerceScreen() + .setCategoriesPath(listOf("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload) // Optional. + val showScreenEvent = ECommerceEvent.showScreenEvent(screen) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(showScreenEvent) + ``` + + - Java + + ```java translate=no + Map payload = new HashMap<>(); + payload.put("configuration", "landscape"); + payload.put("full_screen", "true"); + // Creating a screen object. + CommerceScreen screen = new ECommerceScreen() + .setCategoriesPath(Arrays.asList("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload); // Optional. + ECommerceEvent showScreenEvent = ECommerceEvent.showScreenEvent(screen); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(showScreenEvent); + ``` + + {% endlist %} + +{% endcut %} + +{% cut "Просмотр карточки товара" %} + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val payload = mapOf( + "configuration" to "landscape", + "full_screen" to "true", + ) + // Creating a screen object. + val screen = ECommerceScreen() + .setCategoriesPath(listOf("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload) // Optional. + // Creating an actualPrice object. + val actualPrice = ECommercePrice(ECommerceAmount(4.53, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30570000, "wood"), + ECommerceAmount(26.89, "iron"), + ECommerceAmount(BigDecimal("5.1"), "gold") + )) + // Creating an originalPrice object. + val originalPrice = ECommercePrice(ECommerceAmount(5.78, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30590000, "wood"), + ECommerceAmount(26.92, "iron"), + ECommerceAmount(BigDecimal("5.5"), "gold") + )) + // Creating a product object. + val product = ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(listOf("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(listOf("Продукты", "Молочные продукты", "Йогурты")) // Optional. + val showProductCardEvent = ECommerceEvent.showProductCardEvent(product, screen) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(showProductCardEvent) + ``` + + - Java + + ```java translate=no + Map payload = new HashMap<>(); + payload.put("configuration", "landscape"); + payload.put("full_screen", "true"); + // Creating a screen object. + ECommerceScreen screen = new ECommerceScreen() + .setCategoriesPath(Arrays.asList("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload); // Optional. + // Creating an actualPrice object. + ECommercePrice actualPrice = new ECommercePrice(new ECommerceAmount(4.53, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_570_000, "wood"), + new ECommerceAmount(26.89, "iron"), + new ECommerceAmount(new BigDecimal("5.1"), "gold") + )); + // Creating an originalPrice object. + ECommercePrice originalPrice = new ECommercePrice(new ECommerceAmount(5.78, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_590_000, "wood"), + new ECommerceAmount(26.92, "iron"), + new ECommerceAmount(new BigDecimal("5.5"), "gold") + )); + // Creating a product object. + ECommerceProduct product = new ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(Arrays.asList("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(Arrays.asList("Продукты", "Молочные продукты", "Йогурты")); // Optional. + ECommerceEvent showProductCardEvent = ECommerceEvent.showProductCardEvent(product, screen); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(showProductCardEvent); + ``` + + {% endlist %} + +{% endcut %} + +{% cut "Просмотр страницы товара" %} + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val payload = mapOf( + "configuration" to "landscape", + "full_screen" to "true", + ) + // Creating a screen object. + val screen = ECommerceScreen() + .setCategoriesPath(listOf("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload) // Optional. + // Creating an actualPrice object. + val actualPrice = ECommercePrice(ECommerceAmount(4.53, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30570000, "wood"), + ECommerceAmount(26.89, "iron"), + ECommerceAmount(BigDecimal("5.1"), "gold") + )) + // Creating an originalPrice object. + val originalPrice = ECommercePrice(ECommerceAmount(5.78, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30590000, "wood"), + ECommerceAmount(26.92, "iron"), + ECommerceAmount(BigDecimal("5.5"), "gold") + )) + // Creating a product object. + val product = ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(listOf("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(listOf("Продукты", "Молочные продукты", "Йогурты")) // Optional. + // Creating a referrer object. + val referrer = ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen) // Optional. + val showProductDetailsEvent = ECommerceEvent.showProductDetailsEvent(product, referrer) // Referrer is optional — can be null. + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(showProductDetailsEvent) + ``` + + - Java + + ```java translate=no + Map payload = new HashMap<>(); + payload.put("configuration", "landscape"); + payload.put("full_screen", "true"); + // Creating a screen object. + ECommerceScreen screen = new ECommerceScreen() + .setCategoriesPath(Arrays.asList("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload); // Optional. + // Creating an actualPrice object. + ECommercePrice actualPrice = new ECommercePrice(new ECommerceAmount(4.53, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_570_000, "wood"), + new ECommerceAmount(26.89, "iron"), + new ECommerceAmount(new BigDecimal("5.1"), "gold") + )); + // Creating an originalPrice object. + ECommercePrice originalPrice = new ECommercePrice(new ECommerceAmount(5.78, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_590_000, "wood"), + new ECommerceAmount(26.92, "iron"), + new ECommerceAmount(new BigDecimal("5.5"), "gold") + )); + // Creating a product object. + ECommerceProduct product = new ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(Arrays.asList("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(Arrays.asList("Продукты", "Молочные продукты", "Йогурты")); // Optional. + // Creating a referrer object. + ECommerceReferrer referrer = new ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen); // Optional. + ECommerceEvent showProductDetailsEvent = ECommerceEvent.showProductDetailsEvent(product, referrer); // Referrer is optional — can be null. + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(showProductDetailsEvent); + ``` + + {% endlist %} + +{% endcut %} + +{% cut "Добавление или удаление товара из корзины" %} + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val payload = mapOf( + "configuration" to "landscape", + "full_screen" to "true", + ) + // Creating a screen object. + val screen = ECommerceScreen() + .setCategoriesPath(listOf("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload) // Optional. + // Creating an actualPrice object. + val actualPrice = ECommercePrice(ECommerceAmount(4.53, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30570000, "wood"), + ECommerceAmount(26.89, "iron"), + ECommerceAmount(BigDecimal("5.1"), "gold") + )) + // Creating an originalPrice object. + val originalPrice = ECommercePrice(ECommerceAmount(5.78, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30590000, "wood"), + ECommerceAmount(26.92, "iron"), + ECommerceAmount(BigDecimal("5.5"), "gold") + )) + // Creating a product object. + val product = ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(listOf("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(listOf("Продукты", "Молочные продукты", "Йогурты")) // Optional. + // Creating a referrer object. + val referrer = ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen) // Optional. + // Creating a cartItem object. + val addedItems1 = ECommerceCartItem(product, actualPrice, 1.0) + .setReferrer(referrer) // Optional. + val addCartItemEvent = ECommerceEvent.addCartItemEvent(addedItems1) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(addCartItemEvent) + val removeCartItemEvent = ECommerceEvent.removeCartItemEvent(addedItems1) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(removeCartItemEvent) + ``` + + - Java + + ```java translate=no + Map payload = new HashMap<>(); + payload.put("configuration", "landscape"); + payload.put("full_screen", "true"); + // Creating a screen object. + ECommerceScreen screen = new ECommerceScreen() + .setCategoriesPath(Arrays.asList("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload); // Optional. + // Creating an actualPrice object. + ECommercePrice actualPrice = new ECommercePrice(new ECommerceAmount(4.53, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_570_000, "wood"), + new ECommerceAmount(26.89, "iron"), + new ECommerceAmount(new BigDecimal("5.1"), "gold") + )); + // Creating an originalPrice object. + ECommercePrice originalPrice = new ECommercePrice(new ECommerceAmount(5.78, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_590_000, "wood"), + new ECommerceAmount(26.92, "iron"), + new ECommerceAmount(new BigDecimal("5.5"), "gold") + )); + // Creating a product object. + ECommerceProduct product = new ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(Arrays.asList("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(Arrays.asList("Продукты", "Молочные продукты", "Йогурты")); // Optional. + // Creating a referrer object. + ECommerceReferrer referrer = new ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen); // Optional. + // Creating a cartItem object. + ECommerceCartItem addedItems1 = new ECommerceCartItem(product, actualPrice, 1.0) + .setReferrer(referrer); // Optional. + ECommerceEvent addCartItemEvent = ECommerceEvent.addCartItemEvent(addedItems1); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(addCartItemEvent); + ECommerceEvent removeCartItemEvent = ECommerceEvent.removeCartItemEvent(addedItems1); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(removeCartItemEvent); + ``` + + {% endlist %} + +{% endcut %} + +{% cut "Начало оформления и завершение покупки" %} + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val payload = mapOf( + "configuration" to "landscape", + "full_screen" to "true", + ) + // Creating a screen object. + val screen = ECommerceScreen() + .setCategoriesPath(listOf("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload) // Optional. + // Creating an actualPrice object. + val actualPrice = ECommercePrice(ECommerceAmount(4.53, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30570000, "wood"), + ECommerceAmount(26.89, "iron"), + ECommerceAmount(BigDecimal("5.1"), "gold") + )) + // Creating an originalPrice object. + val originalPrice = ECommercePrice(ECommerceAmount(5.78, "USD")) + .setInternalComponents(listOf( // Optional. + ECommerceAmount(30590000, "wood"), + ECommerceAmount(26.92, "iron"), + ECommerceAmount(BigDecimal("5.5"), "gold") + )) + // Creating a product object. + val product = ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(listOf("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(listOf("Продукты", "Молочные продукты", "Йогурты")) // Optional. + // Creating a referrer object. + val referrer = ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen) // Optional. + // Creating a cartItem object. + val addedItems1 = ECommerceCartItem(product, actualPrice, 1.0) + .setReferrer(referrer) // Optional. + // Creating an order object. + val order = ECommerceOrder("88528768", listOf(addedItems1)) + .setPayload(payload) // Optional. + val beginCheckoutEvent = ECommerceEvent.beginCheckoutEvent(order) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(beginCheckoutEvent) + val purchaseEvent = ECommerceEvent.purchaseEvent(order) + // Sending an e-commerce event. + AppMetrica.getReporter(applicationContext, "Testing API key").reportECommerce(purchaseEvent) + ``` + + - Java + + ```java translate=no + Map payload = new HashMap<>(); + payload.put("configuration", "landscape"); + payload.put("full_screen", "true"); + // Creating a screen object. + ECommerceScreen screen = new ECommerceScreen() + .setCategoriesPath(Arrays.asList("Акции", "Красная цена")) // Optional. + .setName("ProductCardActivity") // Optional. + .setSearchQuery("даниссимо кленовый сироп") // Optional. + .setPayload(payload); // Optional. + // Creating an actualPrice object. + ECommercePrice actualPrice = new ECommercePrice(new ECommerceAmount(4.53, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_570_000, "wood"), + new ECommerceAmount(26.89, "iron"), + new ECommerceAmount(new BigDecimal("5.1"), "gold") + )); + // Creating an originalPrice object. + ECommercePrice originalPrice = new ECommercePrice(new ECommerceAmount(5.78, "USD")) + .setInternalComponents(Arrays.asList( // Optional. + new ECommerceAmount(30_590_000, "wood"), + new ECommerceAmount(26.92, "iron"), + new ECommerceAmount(new BigDecimal("5.5"), "gold") + )); + // Creating a product object. + ECommerceProduct product = new ECommerceProduct("779213") + .setActualPrice(actualPrice) // Optional. + .setPromocodes(Arrays.asList("BT79IYX", "UT5412EP")) // Optional. + .setPayload(payload) // Optional. + .setOriginalPrice(originalPrice) // Optional. + .setName("Продукт творожный «Даниссимо» 5.9%, 130 г.") // Optional. + .setCategoriesPath(Arrays.asList("Продукты", "Молочные продукты", "Йогурты")); // Optional. + // Creating a referrer object. + ECommerceReferrer referrer = new ECommerceReferrer() + .setType("button") // Optional. + .setIdentifier("76890") // Optional. + .setScreen(screen); // Optional. + // Creating a cartItem object. + ECommerceCartItem addedItems1 = new ECommerceCartItem(product, actualPrice, 1.0) + .setReferrer(referrer); // Optional. + // Creating an order object. + ECommerceOrder order = new ECommerceOrder("88528768", Arrays.asList(addedItems1)) + .setPayload(payload); // Optional. + ECommerceEvent beginCheckoutEvent = ECommerceEvent.beginCheckoutEvent(order); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(beginCheckoutEvent); + ECommerceEvent purchaseEvent = ECommerceEvent.purchaseEvent(order); + // Sending an e-commerce event. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportECommerce(purchaseEvent); + ``` + + {% endlist %} + +{% endcut %} + +### Шаг 2. Проверьте отчет тестового приложения {#send-ecommerce-test-app} + +Совершите тестовые покупки в приложении. Через некоторое время в интерфейсе AppMetrica проверьте отчет «Ecommerce». Убедитесь, что ECommerce-события отображаются в отчете. + +Подробнее об отчете в разделе. + +### Шаг 3. Настройте отправку на основной API key {#send-ecommerce-key} + +После успешного тестирования настройте отправку ECommerce-событий на основной API key. + +Чтобы отправить объект `ECommerceEvent` на основной API key, используйте метод `AppMetrica.reportECommerce(@NonNull ECommerceEvent event)`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // ... + // Sending an e-commerce event. + AppMetrica.reportECommerce(ecommerceEvent) + ``` + +- Java + + ```java translate=no + // ... + // Sending an e-commerce event. + AppMetrica.reportECommerce(ecommerceEvent); + ``` + +{% endlist %} + +## Отправка Revenue {#send-revenue} + +AppMetrica поддерживает валидацию покупок, которые реализованы с помощью библиотеки [Google Play Billing](https://developer.android.com/google/play/billing/billing_overview). Валидация позволяет фильтровать покупки, которые совершаются из взломанных приложений. Если валидация включена и покупка не проходит валидацию, она не отображается в отчетах. + +{% note info %} + + Для валидации покупок на Android используется локальная валидация с помощью публичного ключа. Чтобы включить валидацию, создайте публичный ключ и укажите его в настройках. + + {% endnote %} + +### Шаг 1. Настройте отправку Revenue на тестовый API key {#send-revenue-test-key} + +В AppMetrica нет возможности сегментировать Revenue на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые покупки будут попадать в общую статистику. Поэтому, чтобы отладить отправку Revenue, используйте отправку статистики на дополнительный API key с помощью репортера. + +Ниже описаны этапы отправки Revenue на дополнительный API key: + +{% cut "С валидацией" %} + + Чтобы покупки на Android валидировались, настройте отправку объекта `Revenue.Receipt` вместе с `Revenue`: + + 1. Создайте объект `Revenue.Receipt` с информацией о покупке и подписью. Его необходимо использовать при создании объекта `Revenue` в методе `Revenue.Builder.withReceipt(Revenue.Receipt receipt)`. + 2. Создайте объект `Revenue` с помощью конструктора `Revenue.Builder`. + 3. Отправьте объект `Revenue` на тестовый API key с помощью репортера `IReporter`. Подробнее о работе репортеров в разделе [Отправка статистики на дополнительный API key](#reporter-different-apikey). + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + fun handlePurchase(purchase: Purchase) { + // Creating the Revenue.Receipt instance. + // It is used for checking purchases in Google Play. + val revenueReceipt = Receipt.newBuilder() + .withData(purchase.originalJson) + .withSignature(purchase.signature) + .build() + // Creating the Revenue instance. + val revenue = Revenue.newBuilder(99000000, Currency.getInstance("RUB")) + .withProductID("io.appmetrica.service.299") + .withQuantity(2) + .withReceipt(revenueReceipt) + .withPayload("""{"source":"Google Play"}""") + .build() + // Sending the Revenue instance using reporter. + AppMetrica.getReporter(applicationContext, "Testing API key").reportRevenue(revenue) + } + ``` + + - Java + + ```java translate=no + void handlePurchase(Purchase purchase) { + // Creating the Revenue.Receipt instance. + // It is used for checking purchases in Google Play. + Revenue.Receipt revenueReceipt = Revenue.Receipt.newBuilder() + .withData(purchase.getOriginalJson()) + .withSignature(purchase.getSignature()) + .build(); + // Creating the Revenue instance. + Revenue revenue = Revenue.newBuilder(99000000, Currency.getInstance("RUB")) + .withProductID("io.appmetrica.service.299") + .withQuantity(2) + .withReceipt(revenueReceipt) + .withPayload("{\"source\":\"Google Play\"}") + .build(); + // Sending the Revenue instance using reporter. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportRevenue(revenue); + } + ``` + + {% endlist %} + +{% endcut %} + +{% cut "Без валидации" %} + + Чтобы отправить информацию о покупке без валидации: + + 1. Создайте объект `Revenue` с помощью конструктора `Revenue.Builder`. + 2. (Опционально) Чтобы группировать покупки по `OrderID`, укажите его в методе `Revenue.Builder.withPayload(String payload)`. + + {% note info %} + + Если идентификатор `OrderID` не указан, AppMetrica генерирует идентификатор автоматически. + + {% endnote %} + + 3. Отправьте объект `Revenue` на тестовый API key с помощью репортера `IReporter`. Подробнее о работе репортеров в разделе [Отправка статистики на дополнительный API key](#reporter-different-apikey). + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + // Creating the Revenue instance. + val revenue = Revenue.newBuilder(99000000, Currency.getInstance("RUB")) + .withProductID("io.appmetrica.service.299") + .withQuantity(2) // Passing the OrderID parameter in the .withPayload(String payload) method to group purchases. + .withPayload("""{"OrderID":"Identifier", "source":"Google Play"}""") + .build() + // Sending the Revenue instance using reporter. + AppMetrica.getReporter(applicationContext, "Testing API key").reportRevenue(revenue) + ``` + + - Java + + ```java translate=no + // Creating the Revenue instance. + Revenue revenue = Revenue.newBuilder(99000000, Currency.getInstance("RUB")) + .withProductID("io.appmetrica.service.299") + .withQuantity(2) + // Passing the OrderID parameter in the .withPayload(String payload) method to group purchases. + .withPayload("{\"OrderID\":\"Identifier\", \"source\":\"Google Play\"}") + .build(); + // Sending the Revenue instance using reporter. + AppMetrica.getReporter(getApplicationContext(), "Testing API key").reportRevenue(revenue); + ``` + + {% endlist %} + +{% endcut %} + +### Шаг 2. Проверьте отчет тестового приложения {#send-revenue-test-app} + +В интерфейсе AppMetrica проверьте отчет «Revenue». Убедитесь, что количество покупок увеличилось. + +Подробнее об отчете в разделе. + +### Шаг 3. Настройте отправку Revenue на основной API key {#send-revenue-key} + +После успешного тестирования настройте отправку `Revenue` на основной API key. + +Чтобы отправить объект `Revenue` на основной API key, используйте метод `AppMetrica.reportRevenue(Revenue revenue)`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // ... + // Sending the Revenue instance. + AppMetrica.reportRevenue(revenue) + ``` + +- Java + + ```java translate=no + // ... + // Sending the Revenue instance. + AppMetrica.reportRevenue(revenue); + ``` + +{% endlist %} + +## Отправка Ad Revenue {#send-adrevenue} + +В AppMetrica реализовано несколько вариантов для отправки Ad Revenue из сервисов рекламной монетизации и медиации: + +- [Автоматическая интеграция](#send-adrevenue-automatic-integration). Поддерживается для ironSource. +- [Упрощенная интеграция](#send-adrevenue-simple-integration). Поддерживается для: + - [Applovin MAX](#send-adrevenue-simple-integration-applovin-max) + - [Digital Turbine](#send-adrevenue-simple-integration-digital-turbine) + - [Google AdMob](#send-adrevenue-simple-integration-google-admob) +- [Ручная интеграция/самостоятельная настройка](#send-adrevenue-manual-integration). + +### Автоматическая интеграция {#send-adrevenue-automatic-integration} + +Данные передаются автоматически. При необходимости автосбор можно отключить. + +#### ironSource {#send-adrevenue-automatic-integration-ironsource} + +##### Шаг 1. Настройте отправку Ad Revenue {#send-adrevenue-automatic-integration-ironsource-send} + +Для ironSource поддержан автоматический сбор Ad Revenue. За это отвечает модуль `io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7`. + +{% include notitle%} + +##### Шаг 2. Убедитесь, что Ad Revenue отображается в отчетах {#send-adrevenue-automatic-integration-ironsource-check-reports} + +{% include notitle %} + +##### Отключение автосбора Ad Revenue {#send-adrevenue-automatic-integration-ironsource-off} + +Если вам необходимо отключить автосбор Ad Revenue, то исключите модуль из списка зависимостей: + +{% list tabs %} + +- build.gradle.kts + + ```kotlin translate=no + configurations.configureEach { + exclude(group = "io.appmetrica.analytics", module = "io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7") + } + ``` + +- build.gradle + + ```groovy translate=no + configurations.configureEach { + exclude group: 'io.appmetrica.analytics', module: 'io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7' + } + ``` + +{% endlist %} + +### Упрощенная интеграция {#send-adrevenue-simple-integration} + +Используйте упрощенный API для отправки данных. Он поддерживает популярные сервисы рекламной монетизации и медиации. + +#### Applovin MAX {#send-adrevenue-simple-integration-applovin-max} + +##### Шаг 1. Убедитесь, что SDK активирован {#send-adrevenue-simple-integration-applovin-max-active} + +{% include notitle %} + +##### Шаг 2. Настройте отправку Ad Revenue {#send-adrevenue-simple-integration-applovin-max-send} + +1. После создания соответствующего рекламного объекта установите `MaxAdRevenueListener`, используя метод `setRevenueListener`. +2. Из метода `onAdRevenuePaid(MaxAd)` отправьте данные в AppMetrica SDK: вызвовите метод `AppMetrica#reportExternalAdRevenue` и передайте в качестве аргументов параметр, переданный в слушатель `MaxAd` и экземпляр `AppLovinSdk`. + + {% list tabs %} + + - App open ad + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val maxAppOpenAdView = MaxAppOpenAd( "ad-unit-ID", applicationContext) + maxAppOpenAdView.setRevenueListener { + AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) + } + ``` + + - Java + + ```java translate=no + MaxAppOpenAd maxAppOpenAd = new MaxAppOpenAd( "ad-unit-ID", getApplicationContext()); + maxAppOpenAd.setRevenueListener(maxAdRevenue -> + AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext()))); + ``` + + {% endlist %} + + - Banner + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val maxAdView = MaxAdView("ad-unit-ID", applicationContext) + maxAdView.setRevenueListener { + AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) + } + ``` + + - Java + + ```java translate=no + MaxAdView maxAdView = new MaxAdView("ad-unit-ID", getApplicationContext()); + maxAdView.setRevenueListener(maxAdRevenue -> + AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext()))); + ``` + + {% endlist %} + + - Interstitial + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val maxInterstitialAd = MaxInterstitialAd("ad-unit-ID", applicationContext) + maxInterstitialAd.setRevenueListener { + AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) + } + ``` + + - Java + + ```java translate=no + MaxInterstitialAd maxInterstitialAd = new MaxInterstitialAd("ad-unit-ID", getApplicationContext()); + maxInterstitialAd.setRevenueListener(maxAdRevenue -> + AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext()))); + ``` + + {% endlist %} + + - Native + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val nativeAdLoader = MaxNativeAdLoader("ad-unit-ID", applicationContext) + nativeAdLoader.setRevenueListener { + AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) + } + ``` + + - Java + + ```java translate=no + MaxNativeAdLoader maxNativeAdLoader = new MaxNativeAdLoader("ad-unit-ID", getApplicationContext()); + maxNativeAdLoader.setRevenueListener(maxAdRevenue -> + AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext()))); + ``` + + {% endlist %} + + - Rewarded + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val maxRewardedAd = MaxRewardedAd.getInstance("ad-unit-ID", applicationContext); + maxRewardedAd.setRevenueListener { + AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) + } + ``` + + - Java + + ```java translate=no + MaxRewardedAd maxRewardedAd = MaxRewardedAd.getInstance("ad-unit-ID", getApplicationContext()); + maxRewardedAd.setRevenueListener(maxAdRevenue -> + AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext()))); + ``` + + {% endlist %} + + {% endlist %} + +##### Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах {#send-adrevenue-simple-integration-applovin-max-check-reports} + +{% include notitle %} + +#### Digital Turbine {#send-adrevenue-simple-integration-digital-turbine} + +##### Шаг 1. Убедитесь, что SDK активирован {#send-adrevenue-simple-integration-digital-turbine-active} + +{% include notitle %} + +##### Шаг 2. Настройте отправку Ad Revenue {#send-adrevenue-simple-integration-digital-turbine-send} + +1. Для необходимых типов рекламы (`Banner`, `Interstitial`, `Rewarded`) устанавите соответствующий слушатель (`BannerListener`, `InterstitalListener`, `RewardedListener`). +2. Из метода `onShow` слушателя настройте отправку `impressionData` в AppMetrica SDK c помощью метода `AppMetrica#reportExternalAdRevenue()`. + + {% list tabs %} + + - Banner + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + Banner.setBannerListener(object:BannerListener { + //.... + override fun onShow(placementId: String, impressionData: ImpressionData) { + AppMetrica.reportAdRevenue(impressionData) + //..... + } + //.... + }) + ``` + + - Java + + ```java translate=no + Banner.setBannerListener(new BannerListener() { + //...... + @Override + public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { + AppMetrica.reportExternalAttribution(impressionData); + //...... + } + //...... + }); + ``` + + {% endlist %} + + - Interstitial + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + Interstitial.setInterstitialListener(object:InterstitialListener { + //.... + override fun onShow(placementId: String, impressionData: ImpressionData) { + AppMetrica.reportExternalAdRevenue(impressionData) + //.... + } + //.... + }) + ``` + + - Java + + ```java translate=no + Interstitial.setInterstitialListener(new InterstitialListener() { + //...... + @Override + public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { + AppMetrica.reportExternalAdRevenue(impressionData); + //...... + } + //....... + }); + ``` + + {% endlist %} + + - Rewarded + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + Rewarded.setRewardedListener(object:RewardedListener { + override fun onShow(placementId: String, impressionData: ImpressionData) { + AppMetrica.reportExternalAdRevenue(impressionData); + //....... + } + }) + ``` + + - Java + + ```java translate=no + Rewarded.setRewardedListener(new RewardedListener() { + //..... + @Override + public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { + AppMetrica.reportExternalAdRevenue(impressionData); + //...... + } + //..... + }); + ``` + + {% endlist %} + + {% endlist %} + +##### Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах {#send-adrevenue-simple-integration-digital-turbine-check-reports} + +{% include notitle %} + +#### Google AdMob {#send-adrevenue-simple-integration-google-admob} + +##### Шаг 1. Убедитесь, что SDK активирован {#send-adrevenue-simple-integration-google-admob-active} + +{% include notitle %} + +##### Шаг 2. Настройте отправку Ad Revenue {#send-adrevenue-simple-integration-google-admob-send} + +{% list tabs %} + +- App open ad + + 1. В методе `AppOpenAdLoadCallback#onAdLoaded` слушателя загрузки рекламы установите слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `AppOpenAd`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + AppOpenAd.load( + this, + "ad-unit-ID", + adRequest, + AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, + object : AppOpenAdLoadCallback() { + override fun onAdLoaded(adMobAppOpenAd: AppOpenAd) { + super.onAdLoaded(adMobAppOpenAd) + adMobAppOpenAd.onPaidEventListener = + OnPaidEventListener { adValue -> + AppMetrica.reportExternalAdRevenue( + adValue, + adMobAppOpenAd + ) + //...... + } + //...... + } + }) + ``` + + - Java + + ```java translate=no + AppOpenAd.load( + this, + "ad-unit-ID", + adRequest, + AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, + new RewardedInterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull AppOpenAd adMobAppOpenAd) { + super.onAdLoaded(adMobAppOpenAd); + adMobAppOpenAd.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, adMobAppOpenAd); + //...... + }); + //...... + } + }); + ``` + + {% endlist %} + +- Banner + + 1. После создания `adView` и до загрузки рекламы с помощью вызова `setOnPaidEventListener` зарегистрируйте слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `adView`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val adMobAdView = AdView(this) + //........ + adMobAdView.setOnPaidEventListener { + AppMetrica.reportExternalAdRevenue(it, adMobAdView) + //....... + } + //........ + adMobAdView.loadAd(adRequest) + ``` + + - Java + + ```java translate=no + AdView adMobAdView = new AdView(this); + //...... + adMobAdView.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, adMobAdView); + //....... + }); + //....... + adMobAdView.loadAd(adRequest); + ``` + + {% endlist %} + +- Interstitial + + 1. В методе `InterstitialAdLoadCallback#onAdLoaded` слушателя загрузки рекламы установите слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `interstitialAd`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + InterstitialAd.load(this, "add-unit-ID", adRequest, object : InterstitialAdLoadCallback() { + //...... + override fun onAdLoaded(adMobInterstitalAd: InterstitialAd) { + super.onAdLoaded(adMobInterstitalAd) + //....... + adMobInterstitalAd.setOnPaidEventListener { adValue -> + AppMetrica.reportExternalAdRevenue(adValue, adMobInterstitalAd) + } + //....... + } + }) + ``` + + - Java + + ```java translate=no + InterstitialAd.load(this, "ad-unit-ID", adRequest, new InterstitialAdLoadCallback() { + //........ + @Override + public void onAdLoaded(@NonNull InterstitialAd adMobInterstitialAd) { + super.onAdLoaded(adMobInterstitialAd); + adMobInterstitialAd.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, adMobInterstitialAd); + //...... + }); + //...... + } + }); + ``` + + {% endlist %} + +- Native + + 1. В методе `OnNativeAdLoadedListener#onNativeAdLoaded` слушателя загрузки рекламы установите слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `nativeAd`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + val adMobAdLoader = AdLoader.Builder(this, "add-unit-ID") + .forNativeAd { adMobNativeAd -> + adMobNativeAd.setOnPaidEventListener { adValue -> + AppMetrica.reportExternalAdRevenue(adValue, adMobNativeAd) + } + } + //....... + .build() + //..... + ``` + + - Java + + ```java translate=no + //..... + AdLoader admobLoader = new AdLoader.Builder(this, "ad-unit-ID") + .forNativeAd(adMobNativeAd -> { + adMobNativeAd.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, adMobNativeAd); + //...... + }); + //...... + }) + .build(); + //...... + ``` + + {% endlist %} + +- Rewarded + + 1. В методе `RewardedAdLoadCallback#onAdLoaded` слушателя загрузки рекламы установите слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `rewardedAd`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + //..... + RewardedAd.load(this, "ad-unit-ID", adRequest, object : RewardedAdLoadCallback() { + override fun onAdLoaded(rewardedAd: RewardedAd) { + super.onAdLoaded(rewardedAd) + //..... + rewardedAd.onPaidEventListener = OnPaidEventListener { adValue -> + AppMetrica.reportExternalAdRevenue( + adValue, + rewardedAd + ) + } + } + }) + //..... + ``` + + - Java + + ```java translate=no + //..... + RewardedAd.load(this, "ad-unit-ID", adRequest, new RewardedAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull RewardedAd rewardedAd) { + super.onAdLoaded(rewardedAd); + //..... + rewardedAd.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, rewardedAd); + //........ + }); + } + }); + //..... + ``` + + {% endlist %} + +- Rewarded interstitial + + 1. В методе `RewardedInterstitialAdLoadCallback#onAdLoaded` слушателя загрузки рекламы установите слушатель `OnPaidEventListener`. + 2. В методе `OnPaidEventListener#onPaidEvent` настройте отправку данных в AppMetrica с помощью метода `AppMetrica#reportExternalAdRevenue()`, передав в качестве аргументов полученный объект `AdValue` и `rewardedInterstitialAd`. + + {% list tabs group=instructions %} + + - Kotlin + + ```kotlin translate=no + RewardedInterstitialAd.load( + this, + "ad-unit-ID", + adRequest, + object : RewardedInterstitialAdLoadCallback() { + override fun onAdLoaded(rewardedInterstitialAd: RewardedInterstitialAd) { + super.onAdLoaded(rewardedInterstitialAd) + rewardedInterstitialAd.onPaidEventListener = + OnPaidEventListener { adValue -> + AppMetrica.reportExternalAdRevenue( + adValue, + rewardedInterstitialAd + ) + //...... + } + //...... + } + }) + ``` + + - Java + + ```java translate=no + RewardedInterstitialAd.load(this, "ad-unit-ID", adRequest, new RewardedInterstitialAdLoadCallback() { + @Override + public void onAdLoaded(@NonNull RewardedInterstitialAd rewardedInterstitialAd) { + super.onAdLoaded(rewardedInterstitialAd); + rewardedInterstitialAd.setOnPaidEventListener(adValue -> { + AppMetrica.reportExternalAdRevenue(adValue, rewardedInterstitialAd); + //...... + }); + //...... + } + }); + ``` + + {% endlist %} + +{% endlist %} + +##### Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах {#send-adrevenue-simple-integration-google-admob-check-reports} + +{% include notitle %} + +### Ручная интеграция/самостоятельная настройка {#send-adrevenue-manual-integration} + +Используйте этот вариант, чтобы самостоятельно настроить передачу данных любого другого сервиса рекламной монетизации, который предоставляет Impression level Revenue Data. + +#### Шаг 1. Убедитесь, что SDK активирован {#send-adrevenue-manual-integration-active} + +{% include notitle %} + +#### Шаг 2. Настройте отправку Ad Revenue {#send-adrevenue-manual-integration-send} + +1. Создайте объект `AdRevenue` с помощью конструктора `AdRevenue.Builder`. + + ```java translate=no + Map adRevenuePayload = new HashMap<>(); + adRevenuePayload.put("payload_key_1", "payload_value_1"); + adRevenuePayload.put("payload_key_2", "payload_value_2"); + AdRevenue adRevenue = AdRevenue.newBuilder(new BigDecimal("100.100"), Currency.getInstance("USD")) + .withAdNetwork("ad_network") + .withAdPlacementId("ad_placement_id") + .withAdPlacementName("ad_placement_name") + .withAdType(AdType.NATIVE) + .withAdUnitId("ad_unit_id") + .withAdUnitName("ad_unit_name") + .withPrecision("some precision") + .withPayload(adRevenuePayload) + .build(); + ``` + +2. Отправьте объект `Ad Revenue` с помощью метода `AppMetrica.reportAdRevenue(AdRevenue adRevenue)`. + + ```java translate=no + AppMetrica.reportAdRevenue(adRevenue); + ``` + +#### Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах {#send-adrevenue-manual-integration-check-reports} + +{% include notitle %} + +## Установка длительности тайм-аута сессии {#session-timeout} + +По умолчанию длительность таймаута сессии равна 10 секундам. Это минимально допустимое значение параметра `sessionTimeout`. + +Чтобы изменить длительность таймаута, передайте значение в секундах в метод `withSessionTimeout(int sessionTimeout)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting the length of the session timeout. + .withSessionTimeout(15) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting the length of the session timeout. + .withSessionTimeout(15) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +## Установка версии приложения {#version-app} + +По умолчанию версия приложения задается в файле [build.gradle](https://developer.android.com/studio/publish/versioning). + +Чтобы указать версию приложения из кода, передайте версию приложения в метод `withAppVersion(String appVersion)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting the app version. + .withAppVersion("1.13.2") + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Setting the app version. + .withAppVersion("1.13.2") + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +где `1.13.2` — версия приложения. + +## Определение уровня API библиотеки (Android) {#level-api-android} + +Чтобы определить уровень API библиотеки из кода приложения, используйте метод `AppMetrica.getLibraryApiLevel()`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val libraryApiLevel = AppMetrica.getLibraryApiLevel() + ``` + +- Java + + ```java translate=no + int libraryApiLevel = AppMetrica.getLibraryApiLevel(); + ``` + +{% endlist %} + +## Определение версии библиотеки {#version-sdk} + +Чтобы определить версию библиотеки из кода приложения, используйте метод `AppMetrica.getLibraryVersion()`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val libraryVersion = AppMetrica.getLibraryVersion() + ``` + +- Java + + ```java translate=no + String libraryVersion = AppMetrica.getLibraryVersion(); + ``` + +{% endlist %} + +## Отслеживание источников установки {#source} + +Отслеживание источников установок в AppMetrica SDK работает по умолчанию. + +## Отслеживание открытий приложения с помощью deeplink {#deeplink} + +Чтобы отслеживать открытия приложения с помощью deeplink, необходимо добавить изменения в Activity, которая обрабатывает deeplink. Отслеживание открытий необходимо для корректного трекинга ремаркетинг-кампаний. + +{% note tip %} + + Для работы с deeplink [поддержите их](https://developer.android.com/training/app-links/deep-linking#adding-filters) в вашем приложении. + +{% endnote %} + +Отслеживание открытий осуществляется с помощью метода `reportAppOpen()`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + class DeeplinkActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if (savedInstanceState == null) { + AppMetrica.reportAppOpen(this) + } + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + AppMetrica.reportAppOpen(intent) + } + } + ``` + +- Java + + ```java translate=no + public class DeeplinkActivity extends Activity { + @Override + protected void onCreate(@Nullable final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + AppMetrica.reportAppOpen(this); + } + } + + @Override + protected void onNewIntent(final Intent intent) { + super.onNewIntent(intent); + AppMetrica.reportAppOpen(intent); + } + } + ``` + +{% endlist %} + +{% note info %} + +На Android можно поддержать открытие. + +{% endnote %} + +См. также. + +## Запрос отложенного deeplink {#deferreddeeplink-request} + +Чтобы запросить отложенный deeplink, передайте в метод `AppMetrica.requestDeferredDeeplink(DeferredDeeplinkListener listener)` объект класса, реализующий интерфейс `DeferredDeeplinkListener`. Метод возвращает отложенный deeplink только при первом запуске приложения после получения Google Play Install Referrer. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.requestDeferredDeeplink(object : DeferredDeeplinkListener { + override fun onDeeplinkLoaded(deeplink: String) { + Log.i("Deeplink", "deeplink = $deeplink") + } + + override fun onError(error: DeferredDeeplinkListener.Error, referrer: String?) { + Log.i("Deeplink", "Error: ${error.description}, unparsed referrer: $referrer") + } + }) + ``` + +- Java + + ```java translate=no + AppMetrica.requestDeferredDeeplink(new DeferredDeeplinkListener() { + @Override + public void onDeeplinkLoaded(@NotNull String deeplink) { + Log.i("Deeplink", "deeplink = " + deeplink); + } + + @Override + public void onError(@NotNull Error error, @Nullable String referrer) { + Log.i("Deeplink", "Error: " + error.getDescription() + ", unparsed referrer: " + referrer); + } + }); + ``` + +{% endlist %} + +Подробнее об отложенных deeplinks в разделе. + +## Запрос параметров отложенного deeplink {#deferreddeeplink-parameters-request} + +Чтобы запросить параметры отложенного deeplink, передайте в метод `AppMetrica.requestDeferredDeeplinkParameters(DeferredDeeplinkParametersListener listener)` объект класса, реализующий интерфейс `DeferredDeeplinkParametersListener`. Метод возвращает параметры отложенного deeplink только при первом запуске приложения после получения Google Play Install Referrer. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + AppMetrica.requestDeferredDeeplinkParameters(object : DeferredDeeplinkParametersListener { + override fun onParametersLoaded(parameters: Map) { + // Processing deeplink parameters. + for (key in parameters.keys) { + Log.i("Deeplink params", "key: $key value: ${parameters[key]}") + } + } + + override fun onError(error: DeferredDeeplinkParametersListener.Error, referrer: String) { + // Handling the error. + Log.e("Error!", error.description) + } + }) + ``` + +- Java + + ```java translate=no + AppMetrica.requestDeferredDeeplinkParameters(new DeferredDeeplinkParametersListener() { + @Override + public void onParametersLoaded(@NotNull Map parameters) { + // Processing deeplink parameters. + for (String key : parameters.keySet()) { + Log.i("Deeplink params", "key: " + key + " value: " + parameters.get(key)); + } + } + + @Override + public void onError(@NotNull Error error, @NotNull String referrer) { + // Handling the error. + Log.e("Error!", error.getDescription()); + } + }); + ``` + +{% endlist %} + +Подробнее об отложенных deeplinks в разделе. + +## Учет новых пользователей {#new-user} + +По умолчанию в момент первого запуска приложения все пользователи определяются как новые. Если AppMetrica SDK подключается к приложению, у которого уже есть активные пользователи, то для корректного отслеживания статистики можно настроить учет новых и старых пользователей. Для этого необходимо инициализировать AppMetrica SDK, используя расширенную стартовую конфигурацию `AppMetricaConfig`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + var isFirstLaunch: Boolean = false + // Implement logic to detect whether the app is opening for the first time. + // For example, you can check for files (settings, databases, and so on), + // which the app creates on its first launch. + if (conditions) { + isFirstLaunch = true + } + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + .handleFirstActivationAsUpdate(!isFirstLaunch) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + boolean isFirstLaunch = false; + // Implement logic to detect whether the app is opening for the first time. + // For example, you can check for files (settings, databases, and so on), + // which the app creates on its first launch. + if (conditions) { + isFirstLaunch = true; + } + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + .handleFirstActivationAsUpdate(!isFirstLaunch) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +## Отключение и включение отправки статистики {#stat} + +Если для отправки статистических данных требуется согласие пользователя, необходимо инициализировать библиотеку с отключенной опцией отправки статистики. Для этого передайте значение `false` в метод `withDataSendingEnabled(boolean value)` при создании расширенной конфигурации библиотеки. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling sending data. + .withDataSendingEnabled(false) + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + ``` + +- Java + + ```java translate=no + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Disabling sending data. + .withDataSendingEnabled(false) + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + ``` + +{% endlist %} + +После того как пользователь дал согласие на отправку статистики (например, в настройках приложения или в соглашении при первом открытии), включите отправку статистики с помощью метода `AppMetrica.setDataSendingEnabled(true)`: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + // Checking the status of the boolean variable. It shows the user confirmation. + if (flag) { + // Enabling sending data. + AppMetrica.setDataSendingEnabled(true) + } + ``` + +- Java + + ```java translate=no + // Checking the status of the boolean variable. It shows the user confirmation. + if (flag) { + // Enabling sending data. + AppMetrica.setDataSendingEnabled(true); + } + ``` + +{% endlist %} + +### Пример оповещения {#stat-alert-example} + +Для информирования пользователей вы можете использовать любой текст. Например: + +Это приложение использует сервис аналитики AppMetrica, предоставляемый компанией ООО «ЯНДЕКС», 119021, Россия,Москва, ул. Л. Толстого, 16 (далее — Яндекс) на [Условиях использования сервиса](https://yandex.ru/legal/metrica_termsofuse/). + +AppMetrica анализирует данные об использовании приложения, в том числе об устройстве, на котором оно функционирует, источнике установки, составляет конверсию и статистику вашей активности в целях продуктовой аналитики, анализа и оптимизации рекламных кампаний, а также для устранения ошибок. Собранная таким образом информация не может идентифицировать вас. + +Информация об использовании вами данного приложения, собранная при помощи инструментов AppMetrica, в обезличенном виде будет передаваться Яндексу и храниться на сервере Яндекса в ЕС и Российской Федерации. Яндекс будет обрабатывать эту информацию для предоставления статистики использования вами приложения, составления для нас отчетов о работе приложения, и предоставления других услуг. + +## Получение различных идентификаторов AppMetrica SDK {#get-ids} + +Чтобы получить различные идентификаторы AppMetrica SDK (`DeviceId`, `DeviceIdHash`, `UUID`) используйте метод `requestStartupParams()`. Для получения `appmetrica_device_id` нужно запрашивать `DeviceIdHash`. + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + val startupParamsCallback = object : StartupParamsCallback { + override fun onReceive( + result: StartupParamsCallback.Result?, + ) { + val deviceIdHash = result?.deviceIdHash + // ... + } + + override fun onRequestError( + reason: StartupParamsCallback.Reason, + result: StartupParamsCallback.Result?, + ) { + // ... + } + } + AppMetrica.requestStartupParams( + this, + startupParamsCallback, + listOf( + StartupParamsCallback.APPMETRICA_UUID, + StartupParamsCallback.APPMETRICA_DEVICE_ID, + StartupParamsCallback.APPMETRICA_DEVICE_ID_HASH + ) + ) + ``` + +- Java + + ```java translate=no + StartupParamsCallback startupParamsCallback = new StartupParamsCallback() { + @Override + public void onReceive(@Nullable Result result) { + if (result != null) { + String deviceId = result.deviceId; + String deviceIdHash = result.deviceIdHash; + String uuid = result.uuid; + } + } + + @Override + public void onRequestError(@NonNull Reason reason, @Nullable Result result) { + // ... + } + }; + AppMetrica.requestStartupParams( + this, + startupParamsCallback, + Arrays.asList( + StartupParamsCallback.APPMETRICA_DEVICE_ID, + StartupParamsCallback.APPMETRICA_DEVICE_ID_HASH, + StartupParamsCallback.APPMETRICA_UUID + ) + ); + ``` + +{% endlist %} + +## Передача типа устройства {#device-type} + +Если вы хотите задать тип устройства, укажите его при создании конфигурации: + +{% list tabs group=instructions %} + +- Kotlin + + ```kotlin translate=no + class YourApplication : Application() { + override fun onCreate() { + super.onCreate() + // Creating an extended library configuration. + val config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Defining the device type + .withDeviceType(PredefinedDeviceTypes.TABLET) + // ... + .build() + // Initializing the AppMetrica SDK. + AppMetrica.activate(applicationContext, config) + // Automatic tracking of user activity. + AppMetrica.enableActivityAutoTracking(this) + } + } + ``` + +- Java + + ```java translate=no + public class YourApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + // Creating an extended library configuration. + AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY) + // Defining the device type + .withDeviceType(PredefinedDeviceTypes.TABLET) + // ... + .build(); + // Initializing the AppMetrica SDK. + AppMetrica.activate(getApplicationContext(), config); + // Automatic tracking of user activity. + AppMetrica.enableActivityAutoTracking(this); + } + } + ``` + +{% endlist %} diff --git a/ru/toc.yaml b/ru/toc.yaml index 887dce82..a1cbb13f 100644 --- a/ru/toc.yaml +++ b/ru/toc.yaml @@ -35,6 +35,16 @@ navigation: rightItems: - type: controls items: + - name: ECommerce + href: about.md + - name: Android + href: features.md + - name: Баннеры + href: about.md + items: + - name: Баннер с внешним переходом + href: features.md + hidden: true - name: Платформа Diplodoc labeled: true href: index.yaml