Примеры использования методов
- Инициализация библиотеки с расширенной конфигурацией
- Отправка статистики на дополнительный API key
- Отслеживание аварийных остановок приложения
- Отслеживание аварийных остановок приложения вручную
- Отслеживание нативных аварийных остановок приложения
- Отправка местоположения устройства библиотекой
- Установка местоположения вручную
- Отправка собственного события
- Отправка собственного события с вложенными параметрами
- Отправка события из JavaScript-кода WebView
- Отправка собственного сообщения об ошибке
- Отправка ProfileId
- Отправка атрибутов профиля
- Отправка ECommerce-событий
- Отправка Revenue
- Установка длительности таймаута сессии
- Установка версии приложения
- Определение уровня API библиотеки (Android)
- Определение версии библиотеки
- Отслеживание источников установки
- Отслеживание открытий приложения с помощью deeplink
- Запрос отложенного deeplink
- Запрос параметров отложенного deeplink
- Учет новых пользователей
- Отключение и включение отправки статистики
- Получение различных идентификаторов AppMetrica SDK
- Передача типа устройства
- Отправка Ad Revenue на Android
Инициализация библиотеки с расширенной конфигурацией
Чтобы инициализировать библиотеку с расширенной стартовой конфигурацией, создайте объект класса AppMetricaConfig
с необходимыми настройками и активируйте библиотеку с помощью метода AppMetrica.activate(Context context, AppMetricaConfig config)
. С помощью расширенной конфигурации можно, например, включить/отключить логирование, установить таймаут сессии, передать параметры для отслеживания предустановленных приложений и т. д.
Настройки расширенной конфигурации применяются с момента инициализации библиотеки.
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)
}
}
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);
}
}
Чтобы настроить библиотеку в процессе работы приложения, используйте методы класса AppMetrica
.
Отправка статистики на дополнительный API key
Отправка данных на дополнительный API key позволяет собирать для каждого API key свою статистику. Это можно использовать для управления доступом к информации. Например, чтобы предоставить доступ к статистике для аналитиков, можно продублировать отправку маркетинговых данных на дополнительный API key и предоставить им доступ к этой статистике. Так у них будет доступ только к той информации, которая им необходима.
Для отправки данных на дополнительный API key необходимо использовать репортеры. С помощью них можно отправлять события, сообщения об ошибках, профили и информацию о покупках в приложении. Репортеры могут работать без инициализации AppMetrica SDK.
Шаг 1. (Опционально) Инициализируйте репортер с расширенной конфигурацией
Чтобы инициализировать репортер с расширенной конфигурацией, создайте объект класса ReporterConfig
с необходимыми настройками и активируйте репортер с помощью метода AppMetrica.activateReporter(Context context, ReporterConfig config)
. Конфигурация применяется для репортера с указанным API key. Для каждого дополнительного API key можно настроить свою конфигурацию.
Внимание
Инициализацию репортера с расширенной конфигурацией необходимо проводить до первого обращения к репортеру. Иначе репортер будет инициализирован без конфигурации.
// 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)
// 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);
Шаг 2. Настройте отправку данных с помощью репортера
Для отправки данных с помощью репортера, необходимо получить объект, который реализует интерфейс IReporter
с помощью метода AppMetrica.getReporter(Context context, String apiKey)
и использовать методы интерфейса для отправки отчетов. Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key.
Пример отправки события:
AppMetrica.getReporter(applicationContext, ANOTHER_API_KEY).reportEvent("Updates installed")
AppMetrica.getReporter(getApplicationContext(), ANOTHER_API_KEY).reportEvent("Updates installed");
Для корректного отслеживания сессий взаимодействия пользователя с приложением настройте отправку событий о начале и приостановке сессии для каждого репортера. Для этого используйте методы resumeSession()
и pauseSession()
интерфейса IReporter
в реализации onResume()
и onPause()
ваших Activity:
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()
}
}
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();
}
}
Отслеживание аварийных остановок приложения
Отчеты об аварийных остановках приложения отправляются по умолчанию.
Чтобы отключить автоматическое отслеживание, инициализируйте библиотеку с конфигурацией, в которой отправка информации об аварийных остановках приложения отключена. Для этого передайте значение false
в метод withCrashReporting(boolean enabled)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
Если автоматическое отслеживание отключено, вы можете отправлять информацию об аварийных остановках вручную.
Отслеживание аварийных остановок приложения вручную
Отчеты об аварийных остановках приложения отправляются по умолчанию. Чтобы избежать дублирования событий при ручной отправке, необходимо отключить автоматическое отслеживание аварийных остановок.
Чтобы отправлять информацию об аварийных остановках приложения вручную, используйте метод AppMetrica.reportUnhandledException(Throwable exception)
:
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)
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);
Отслеживание нативных аварийных остановок приложения
Отчеты о нативных аварийных остановках приложения отправляются автоматически, если SO-файлы библиотеки добавлены в проект. По умолчанию SO-файлы отсутствуют. Чтобы добавить их, настройте крэш-плагин следующим образом:
appmetrica {
...
ndk {
enable = { applicationVariant -> true }
}
}
appmetrica {
...
ndk {
enable = { applicationVariant -> true }
}
}
Плагин автоматически подключит необходимые зависимости. Подключаемая плагином бибилотека содержит so-файлы для всех платформ (arm, armv7, mips, x86). Используйте abi splits для исключения неиспользуемых so-файлов.
Если вы не используете Gradle
Загрузите и добавьте библиотеку в проект.
Чтобы отключить автоматическое отслеживание, инициализируйте библиотеку с конфигурацией, в которой отправка информации о нативных аварийных остановках приложения отключена.
Для этого передайте значение false
в метод withNativeCrashReporting(boolean enabled)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
Узнайте больше
Отправка местоположения устройства библиотекой
Примечание
Отправка местоположения устройства по умолчанию отключена.
Начиная с версии 5.0.0 AppMetrica SDK по умолчанию инициализируется с отключенной опцией locationTracking
.
Чтобы включить отправку, инициализируйте библиотеку с конфигурацией, в которой отправка информации о местоположении устройства включена. Для этого передайте значение true
в метод withLocationTracking(boolean enabled)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
Чтобы включить отправку в процессе работы приложения, используйте метод AppMetrica.setLocationTracking(boolean enabled)
:
AppMetrica.setLocationTracking(true)
AppMetrica.setLocationTracking(true);
Для более точного определения местоположения добавьте в файл AndroidManifest.xml одно из следующих разрешений:
- android.permission.ACCESS_COARSE_LOCATION — для приблизительного определения.
- android.permission.ACCESS_FINE_LOCATION — для точного определения.
Например:
<manifest>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application>...</application>
</manifest>
Установка местоположения вручную
Перед отправкой собственной информации о местоположении устройства убедитесь, что отправка отчетов была включена.
Библиотека определяет местоположение устройства самостоятельно. Чтобы отправить собственную информацию о местоположении устройства, передайте объект класса android.location.Location в метод AppMetrica.setLocation(Location location)
.
// Determining the location.
val currentLocation = ...
// Setting your own location information of the device.
AppMetrica.setLocation(currentLocation)
// Determining the location.
Location currentLocation = ...;
// Setting your own location information of the device.
AppMetrica.setLocation(currentLocation);
Чтобы отправить собственную информацию о местоположении устройства с помощью стартовой конфигурации, передайте объект android.location.Location
в метод withLocation(Location location)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
Чтобы возобновить определение местоположения библиотекой, передайте в метод AppMetrica.setLocation(Location location)
значение null
и настройте отправку местоположения устройства.
AppMetrica.setLocation(null)
AppMetrica.setLocation(null);
Отправка собственного события
Чтобы отправить собственное событие без вложенных параметров, передайте короткое название или описание события в метод AppMetrica.reportEvent(String eventName)
:
AppMetrica.reportEvent("Updates installed")
AppMetrica.reportEvent("Updates installed");
Отправка собственного события с вложенными параметрами
AppMetrica SDK позволяет отправлять собственные события с вложенными параметрами, которые могут быть заданы в формате JSON или в виде набора атрибутов (Map).
JSON
Чтобы передать вложенные параметры события в формате JSON, используйте метод AppMetrica.reportEvent(String eventName, String jsonValue)
:
val eventParameters = """{"name":"Alice", "age":"18"}"""
AppMetrica.reportEvent("New person", eventParameters)
String eventParameters = "{\"name\":\"Alice\", \"age\":\"18\"}";
AppMetrica.reportEvent("New person", eventParameters);
Map
Чтобы передать вложенные параметры события в виде набора атрибутов (Map), используйте метод AppMetrica.reportEvent(String eventName, Map<String, Object> attributes)
:
val eventParameters = mapOf("name" to "Alice", "age" to 18)
AppMetrica.reportEvent("New person", eventParameters)
Map<String, Object> eventParameters = new HashMap<String, Object>();
eventParameters.put("name", "Alice");
eventParameters.put("age", 18);
AppMetrica.reportEvent("New person", eventParameters);
Веб-интерфейс AppMetrica отображает до пяти уровней вложенности события. Если событие содержит шесть уровней и более, в отчете отобразятся пять верхних. С помощью API отчетов можно выгрузить до десяти уровней.
Подробнее о событиях в разделе События.
Отправка события из JavaScript-кода WebView
AppMetrica SDK позволяет отправлять клиентские события из JavaScript-кода. Инициализируйте отправку вызовом метода initWebViewReporting
:
val webView = findViewById<WebView>(R.id.myWebView)
// do your initialization here
webView.settings.javaScriptEnabled = true
AppMetrica.initWebViewReporting(webView)
webView.loadUrl(myURL)
WebView webView = (WebView) findViewById(R.id.myWebView);
// do your initialization here
webView.getSettings().setJavaScriptEnabled(true);
AppMetrica.initWebViewReporting(webView);
webView.loadUrl(myURL);
Вызывайте метод initWebViewReporting
после вызова метода setJavaScriptEnabled
и до вызова loadUrl.
Для отправки события из JavaScript-кода используйте метод reportEvent(name, value)
интерфейса AppMetrica:
Javascript
function buttonClicked() {
AppMetrica.reportEvent('Button clicked!', '{}');
}
Аргументы метода reportEvent
:
name
— строка. Не может быть null или пустым.value
— JSON-строка. Может быть null.
Отправка собственного сообщения об ошибке
Чтобы отправить собственное сообщение об ошибке, используйте методы:
AppMetrica.reportError(String message, Throwable error)
AppMetrica.reportError(String groupIdentifier, String message)
AppMetrica.reportError(String groupIdentifier, String message, Throwable error)
Пример c groupIdentifier
Если ошибки отправляются с помощью методов c groupIdentifier, они группируются по идентификатору.
try {
"00xffWr0ng".toInt()
} catch (error: Throwable) {
AppMetrica.reportError("Your ID", "Error while parsing some integer number", error)
}
try {
Integer.valueOf("00xffWr0ng");
} catch (Throwable error) {
AppMetrica.reportError("Your ID", "Error while parsing some integer number", error);
}
Не используйте переменные значения в качестве идентификатора для группировки. Иначе количество групп будет увеличиваться и их будет сложно анализировать.
Пример c message
Если ошибки отправляются с помощью метода AppMetrica.reportError(String message, Throwable error)
, они группируются по stack trace.
try {
"00xffWr0ng".toInt()
} catch (error: Throwable) {
AppMetrica.reportError("Error while parsing some integer number", error)
}
try {
Integer.valueOf("00xffWr0ng");
} catch (Throwable error) {
AppMetrica.reportError("Error while parsing some integer number", error);
}
Отправка ProfileId
Если идентификатор пользовательского профиля известен до инициализации AppMetrica SDK, передавайте его до инициализации (setUserProfileID
) или во время инициализации с расширенной конфигурацией (withUserProfileID
).
В противном случае будет создан пользовательский профиль с идентификатором appmetrica_device_id
.
Важно
Если отправка ProfileId
не настроена, предопределенные атрибуты не отображаются в веб-интерфейсе.
В любой момент можно обновить ProfileId
с помощью вызова setUserProfileID
:
AppMetrica.setUserProfileID("id")
AppMetrica.setUserProfileID("id");
Отправка атрибутов профиля
Чтобы отправить атрибуты профиля, передайте в объект UserProfile
необходимые атрибуты и отправьте этот объект с помощью метода AppMetrica.reportUserProfile(UserProfile profile)
. Атрибуты профиля создаются с помощью методов класса Attribute
.
// 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)
// 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);
Отправка ECommerce-событий
В AppMetrica нет возможности сегментировать ECommerce-события на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые события будут попадать в общую статистику. Поэтому, чтобы отладить отправку ECommerce-событий, используйте отправку статистики на дополнительный API key с помощью репортера.
Шаг 1. Настройте отправку ECommerce-событий на тестовый API key
Для различных действий пользователя есть соответствующие типы ECommerce-событий. Чтобы создать конкретный тип события, используйте нужный метод класса ECommerceEvent
.
Ниже приведены примеры отправки конкретных типов событий:
Открытие страницы
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)
Map<String, String> 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);
Просмотр карточки товара
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)
Map<String, String> 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);
Просмотр страницы товара
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)
Map<String, String> 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);
Добавление или удаление товара из корзины
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)
Map<String, String> 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);
Начало оформления и завершение покупки
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)
Map<String, String> 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);
Шаг 2. Проверьте отчет тестового приложения
Совершите тестовые покупки в приложении. Через некоторое время в интерфейсе AppMetrica проверьте отчет «Анализ покупок». Убедитесь, что ECommerce-события отображаются в отчете.
Подробнее об отчете в разделе Анализ покупок.
Шаг 3. Настройте отправку на основной API key
После успешного тестирования настройте отправку ECommerce-событий на основной API key.
Чтобы отправить объект ECommerceEvent
на основной API key, используйте метод AppMetrica.reportECommerce(@NonNull ECommerceEvent event)
.
// ...
// Sending an e-commerce event.
AppMetrica.reportECommerce(ecommerceEvent)
// ...
// Sending an e-commerce event.
AppMetrica.reportECommerce(ecommerceEvent);
Отправка Revenue
AppMetrica поддерживает валидацию покупок, которые реализованы с помощью библиотеки Google Play Billing. Валидация позволяет фильтровать покупки, которые совершаются из взломанных приложений. Если валидация включена и покупка не проходит валидацию, она не отображается в отчетах.
Примечание
Для валидации покупок на Android используется локальная валидация с помощью публичного ключа. Чтобы включить валидацию, создайте публичный ключ и укажите его в настройках.
Шаг 1. Настройте отправку Revenue на тестовый API key
В AppMetrica нет возможности сегментировать Revenue на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые покупки будут попадать в общую статистику. Поэтому, чтобы отладить отправку Revenue, используйте отправку статистики на дополнительный API key с помощью репортера.
Ниже описаны этапы отправки Revenue на дополнительный API key:
С валидацией
Чтобы покупки на Android валидировались, настройте отправку объекта Revenue.Receipt
вместе с Revenue
:
- Создайте объект
Revenue.Receipt
с информацией о покупке и подписью. Его необходимо использовать при создании объектаRevenue
в методеRevenue.Builder.withReceipt(Revenue.Receipt receipt)
. - Создайте объект
Revenue
с помощью конструктораRevenue.Builder
. - Отправьте объект
Revenue
на тестовый API key с помощью репортераIReporter
. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.
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)
}
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);
}
Без валидации
Чтобы отправить информацию о покупке без валидации:
-
Создайте объект
Revenue
с помощью конструктораRevenue.Builder
. -
(Опционально) Чтобы группировать покупки по
OrderID
, укажите его в методеRevenue.Builder.withPayload(String payload)
.Примечание
Если идентификатор
OrderID
не указан, AppMetrica генерирует идентификатор автоматически. -
Отправьте объект
Revenue
на тестовый API key с помощью репортераIReporter
. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.
// 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)
// 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);
Шаг 2. Проверьте отчет тестового приложения
В интерфейсе AppMetrica проверьте отчет «Revenue». Убедитесь, что количество покупок увеличилось.
Подробнее об отчете в разделе Revenue.
Шаг 3. Настройте отправку Revenue на основной API key
После успешного тестирования настройте отправку Revenue
на основной API key.
Чтобы отправить объект Revenue
на основной API key, используйте метод AppMetrica.reportRevenue(Revenue revenue)
.
// ...
// Sending the Revenue instance.
AppMetrica.reportRevenue(revenue)
// ...
// Sending the Revenue instance.
AppMetrica.reportRevenue(revenue);
Установка длительности таймаута сессии
По умолчанию длительность таймаута сессии равна 10 секундам. Это минимально допустимое значение параметра sessionTimeout
.
Чтобы изменить длительность таймаута, передайте значение в секундах в метод withSessionTimeout(int sessionTimeout)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
Установка версии приложения
По умолчанию версия приложения задается в файле build.gradle.
Чтобы указать версию приложения из кода, передайте версию приложения в метод withAppVersion(String appVersion)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
где 1.13.2
— версия приложения.
Определение уровня API библиотеки (Android)
Чтобы определить уровень API библиотеки из кода приложения, используйте метод AppMetrica.getLibraryApiLevel()
.
val libraryApiLevel = AppMetrica.getLibraryApiLevel()
int libraryApiLevel = AppMetrica.getLibraryApiLevel();
Определение версии библиотеки
Чтобы определить версию библиотеки из кода приложения, используйте метод AppMetrica.getLibraryVersion()
.
val libraryVersion = AppMetrica.getLibraryVersion()
String libraryVersion = AppMetrica.getLibraryVersion();
Отслеживание источников установки
Отслеживание источников установок в AppMetrica SDK работает по умолчанию.
Отслеживание открытий приложения с помощью deeplink
Чтобы отслеживать открытия приложения с помощью deeplink, необходимо добавить изменения в Activity, которая обрабатывает deeplink. Отслеживание открытий необходимо для корректного трекинга ремаркетинг-кампаний.
Совет
Для работы с deeplink поддержите их в вашем приложении.
Отслеживание открытий осуществляется с помощью метода reportAppOpen()
:
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)
}
}
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);
}
}
Примечание
На Android можно поддержать открытие отложенного deeplink.
Узнайте больше
Как создать ремаркетинг-кампанию в AppMetrica
Запрос отложенного deeplink
Чтобы запросить отложенный deeplink, передайте в метод AppMetrica.requestDeferredDeeplink(DeferredDeeplinkListener listener)
объект класса, реализующий интерфейс DeferredDeeplinkListener
. Метод возвращает отложенный deeplink только при первом запуске приложения после получения Google Play Install Referrer.
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")
}
})
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);
}
});
Подробнее об отложенных deeplinks в разделе Поддержка отложенных deeplinks.
Запрос параметров отложенного deeplink
Чтобы запросить параметры отложенного deeplink, передайте в метод AppMetrica.requestDeferredDeeplinkParameters(DeferredDeeplinkParametersListener listener)
объект класса, реализующий интерфейс DeferredDeeplinkParametersListener
. Метод возвращает параметры отложенного deeplink только при первом запуске приложения после получения Google Play Install Referrer.
AppMetrica.requestDeferredDeeplinkParameters(object : DeferredDeeplinkParametersListener {
override fun onParametersLoaded(parameters: Map<String, String>) {
// 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)
}
})
AppMetrica.requestDeferredDeeplinkParameters(new DeferredDeeplinkParametersListener() {
@Override
public void onParametersLoaded(@NotNull Map<String, String> 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());
}
});
Подробнее об отложенных deeplinks в разделе Поддержка отложенных deeplinks.
Учет новых пользователей
По умолчанию в момент первого запуска приложения все пользователи определяются как новые. Если AppMetrica SDK подключается к приложению, у которого уже есть активные пользователи, то для корректного отслеживания статистики можно настроить учет новых и старых пользователей. Для этого необходимо инициализировать AppMetrica SDK, используя расширенную стартовую конфигурацию AppMetricaConfig
:
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)
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);
Отключение и включение отправки статистики
Если для отправки статистических данных требуется согласие пользователя, необходимо инициализировать библиотеку с отключенной опцией отправки статистики. Для этого передайте значение false
в метод withDataSendingEnabled(boolean value)
при создании расширенной конфигурации библиотеки.
// 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)
// 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);
После того как пользователь дал согласие на отправку статистики (например, в настройках приложения или в соглашении при первом открытии), включите отправку статистики с помощью метода AppMetrica.setDataSendingEnabled(true)
:
// Checking the status of the boolean variable. It shows the user confirmation.
if (flag) {
// Enabling sending data.
AppMetrica.setDataSendingEnabled(true)
}
// Checking the status of the boolean variable. It shows the user confirmation.
if (flag) {
// Enabling sending data.
AppMetrica.setDataSendingEnabled(true);
}
Пример оповещения
Для информирования пользователей вы можете использовать любой текст. Например:
Это приложение использует сервис аналитики AppMetrica, предоставляемый компанией ООО «ЯНДЕКС», 119021, Россия,Москва, ул. Л. Толстого, 16 (далее — Яндекс) на Условиях использования сервиса.
AppMetrica анализирует данные об использовании приложения, в том числе об устройстве, на котором оно функционирует, источнике установки, составляет конверсию и статистику вашей активности в целях продуктовой аналитики, анализа и оптимизации рекламных кампаний, а также для устранения ошибок. Собранная таким образом информация не может идентифицировать вас.
Информация об использовании вами данного приложения, собранная при помощи инструментов AppMetrica, в обезличенном виде будет передаваться Яндексу и храниться на сервере Яндекса в ЕС и Российской Федерации. Яндекс будет обрабатывать эту информацию для предоставления статистики использования вами приложения, составления для нас отчетов о работе приложения, и предоставления других услуг.
Получение различных идентификаторов AppMetrica SDK
Чтобы получить различные идентификаторы AppMetrica SDK (DeviceId
, DeviceIdHash
, UUID
) используйте метод requestStartupParams()
. Для получения appmetrica_device_id
нужно запрашивать DeviceIdHash
.
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
)
)
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
)
);
Передача типа устройства
Если вы хотите задать тип устройства, укажите его при создании конфигурации:
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)
}
}
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);
}
}
Отправка Ad Revenue на Android
В AppMetrica реализовано несколько вариантов для отправки Ad Revenue из сервисов рекламной монетизации и медиации:
- Автоматическая интеграция. Поддерживается для ironSource.
- Упрощенная интеграция. Поддерживается для:
- Applovin MAX
- Digital Turbine
- Google AdMob
- Ручная интеграция/самостоятельная настройка.
Автоматическая интеграция
Данные передаются автоматически. При необходимости автосбор можно отключить.
ironSource
Шаг 1. Настройте отправку Ad Revenue
Для ironSource поддержан автоматический сбор Ad Revenue. За это отвечает модуль io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7
.
Пример активации:
AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY).build();
AppMetrica.activate(context, config);
Шаг 2. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Отключение автосбора Ad Revenue
Если вам необходимо отключить автосбор Ad Revenue, то исключите модуль из списка зависимостей:
configurations.configureEach {
exclude(group = "io.appmetrica.analytics", module = "io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7")
}
configurations.configureEach {
exclude group: 'io.appmetrica.analytics', module: 'io.appmetrica.analytics:analytics-ad-revenue-ironsource-v7'
}
Упрощенная интеграция
Используйте упрощенный API для отправки данных. Он поддерживает популярные сервисы рекламной монетизации и медиации.
Applovin MAX
Шаг 1. Убедитесь, что SDK активирован
Пример активации:
AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY).build();
AppMetrica.activate(context, config);
Шаг 2. Настройте отправку Ad Revenue
-
После создания соответствующего рекламного объекта установите
MaxAdRevenueListener
, используя методsetRevenueListener
. -
Из метода
onAdRevenuePaid(MaxAd)
отправьте данные в AppMetrica SDK: вызвовите методAppMetrica#reportExternalAdRevenue
и передайте в качестве аргументов параметр, переданный в слушательMaxAd
и экземплярAppLovinSdk
.App open adBannerInterstitialNativeRewardedKotlinJavaval maxAppOpenAdView = MaxAppOpenAd( "ad-unit-ID", applicationContext) maxAppOpenAdView.setRevenueListener { AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) }
MaxAppOpenAd maxAppOpenAd = new MaxAppOpenAd( "ad-unit-ID", getApplicationContext()); maxAppOpenAd.setRevenueListener(maxAdRevenue -> AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext())));
KotlinJavaval maxAdView = MaxAdView("ad-unit-ID", applicationContext) maxAdView.setRevenueListener { AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) }
MaxAdView maxAdView = new MaxAdView("ad-unit-ID", getApplicationContext()); maxAdView.setRevenueListener(maxAdRevenue -> AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext())));
KotlinJavaval maxInterstitialAd = MaxInterstitialAd("ad-unit-ID", applicationContext) maxInterstitialAd.setRevenueListener { AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) }
MaxInterstitialAd maxInterstitialAd = new MaxInterstitialAd("ad-unit-ID", getApplicationContext()); maxInterstitialAd.setRevenueListener(maxAdRevenue -> AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext())));
KotlinJavaval nativeAdLoader = MaxNativeAdLoader("ad-unit-ID", applicationContext) nativeAdLoader.setRevenueListener { AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) }
MaxNativeAdLoader maxNativeAdLoader = new MaxNativeAdLoader("ad-unit-ID", getApplicationContext()); maxNativeAdLoader.setRevenueListener(maxAdRevenue -> AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext())));
KotlinJavaval maxRewardedAd = MaxRewardedAd.getInstance("ad-unit-ID", applicationContext); maxRewardedAd.setRevenueListener { AppMetrica.reportExternalAdRevenue(it, AppLovinSdk.getInstance(applicationContext)) }
MaxRewardedAd maxRewardedAd = MaxRewardedAd.getInstance("ad-unit-ID", getApplicationContext()); maxRewardedAd.setRevenueListener(maxAdRevenue -> AppMetrica.reportExternalAdRevenue(maxAdRevenue, AppLovinSdk.getInstance(getApplicationContext())));
Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Digital Turbine
Шаг 1. Убедитесь, что SDK активирован
Пример активации:
AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY).build();
AppMetrica.activate(context, config);
Шаг 2. Настройте отправку Ad Revenue
-
Для необходимых типов рекламы (
Banner
,Interstitial
,Rewarded
) устанавите соответствующий слушатель (BannerListener
,InterstitalListener
,RewardedListener
). -
Из метода
onShow
слушателя настройте отправкуimpressionData
в AppMetrica SDK c помощью методаAppMetrica#reportExternalAdRevenue()
.BannerInterstitialRewardedKotlinJavaBanner.setBannerListener(object:BannerListener { //.... override fun onShow(placementId: String, impressionData: ImpressionData) { AppMetrica.reportAdRevenue(impressionData) //..... } //.... })
Banner.setBannerListener(new BannerListener() { //...... @Override public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { AppMetrica.reportExternalAttribution(impressionData); //...... } //...... });
KotlinJavaInterstitial.setInterstitialListener(object:InterstitialListener { //.... override fun onShow(placementId: String, impressionData: ImpressionData) { AppMetrica.reportExternalAdRevenue(impressionData) //.... } //.... })
Interstitial.setInterstitialListener(new InterstitialListener() { //...... @Override public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { AppMetrica.reportExternalAdRevenue(impressionData); //...... } //....... });
KotlinJavaRewarded.setRewardedListener(object:RewardedListener { override fun onShow(placementId: String, impressionData: ImpressionData) { AppMetrica.reportExternalAdRevenue(impressionData); //....... } })
Rewarded.setRewardedListener(new RewardedListener() { //..... @Override public void onShow(@NonNull String s, @NonNull ImpressionData impressionData) { AppMetrica.reportExternalAdRevenue(impressionData); //...... } //..... });
Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Google AdMob
Шаг 1. Убедитесь, что SDK активирован
Пример активации:
AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY).build();
AppMetrica.activate(context, config);
Шаг 2. Настройте отправку Ad Revenue
-
В методе
AppOpenAdLoadCallback#onAdLoaded
слушателя загрузки рекламы установите слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иAppOpenAd
.KotlinJavaAppOpenAd.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 ) //...... } //...... } })
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); //...... }); //...... } });
-
После создания
adView
и до загрузки рекламы с помощью вызоваsetOnPaidEventListener
зарегистрируйте слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иadView
.KotlinJavaval adMobAdView = AdView(this) //........ adMobAdView.setOnPaidEventListener { AppMetrica.reportExternalAdRevenue(it, adMobAdView) //....... } //........ adMobAdView.loadAd(adRequest)
AdView adMobAdView = new AdView(this); //...... adMobAdView.setOnPaidEventListener(adValue -> { AppMetrica.reportExternalAdRevenue(adValue, adMobAdView); //....... }); //....... adMobAdView.loadAd(adRequest);
-
В методе
InterstitialAdLoadCallback#onAdLoaded
слушателя загрузки рекламы установите слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иinterstitialAd
.KotlinJavaInterstitialAd.load(this, "add-unit-ID", adRequest, object : InterstitialAdLoadCallback() { //...... override fun onAdLoaded(adMobInterstitalAd: InterstitialAd) { super.onAdLoaded(adMobInterstitalAd) //....... adMobInterstitalAd.setOnPaidEventListener { adValue -> AppMetrica.reportExternalAdRevenue(adValue, adMobInterstitalAd) } //....... } })
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); //...... }); //...... } });
-
В методе
OnNativeAdLoadedListener#onNativeAdLoaded
слушателя загрузки рекламы установите слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иnativeAd
.KotlinJavaval adMobAdLoader = AdLoader.Builder(this, "add-unit-ID") .forNativeAd { adMobNativeAd -> adMobNativeAd.setOnPaidEventListener { adValue -> AppMetrica.reportExternalAdRevenue(adValue, adMobNativeAd) } } //....... .build() //.....
//..... AdLoader admobLoader = new AdLoader.Builder(this, "ad-unit-ID") .forNativeAd(adMobNativeAd -> { adMobNativeAd.setOnPaidEventListener(adValue -> { AppMetrica.reportExternalAdRevenue(adValue, adMobNativeAd); //...... }); //...... }) .build(); //......
-
В методе
RewardedAdLoadCallback#onAdLoaded
слушателя загрузки рекламы установите слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иrewardedAd
.KotlinJava//..... 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 ) } } }) //.....
//..... 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); //........ }); } }); //.....
-
В методе
RewardedInterstitialAdLoadCallback#onAdLoaded
слушателя загрузки рекламы установите слушательOnPaidEventListener
. -
В методе
OnPaidEventListener#onPaidEvent
настройте отправку данных в AppMetrica с помощью методаAppMetrica#reportExternalAdRevenue()
, передав в качестве аргументов полученный объектAdValue
иrewardedInterstitialAd
.KotlinJavaRewardedInterstitialAd.load( this, "ad-unit-ID", adRequest, object : RewardedInterstitialAdLoadCallback() { override fun onAdLoaded(rewardedInterstitialAd: RewardedInterstitialAd) { super.onAdLoaded(rewardedInterstitialAd) rewardedInterstitialAd.onPaidEventListener = OnPaidEventListener { adValue -> AppMetrica.reportExternalAdRevenue( adValue, rewardedInterstitialAd ) //...... } //...... } })
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); //...... }); //...... } });
Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Ручная интеграция/самостоятельная настройка
Используйте этот вариант, чтобы самостоятельно настроить передачу данных любого другого сервиса рекламной монетизации, который предоставляет Impression level Revenue Data.
Шаг 1. Убедитесь, что SDK активирован
Пример активации:
AppMetricaConfig config = AppMetricaConfig.newConfigBuilder(API_KEY).build();
AppMetrica.activate(context, config);
Шаг 2. Настройте отправку Ad Revenue
-
Создайте объект
AdRevenue
с помощью конструктораAdRevenue.Builder
.Map<String, String> 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();
-
Отправьте объект
Ad Revenue
с помощью методаAppMetrica.reportAdRevenue(AdRevenue adRevenue)
.AppMetrica.reportAdRevenue(adRevenue);
Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Если вы не нашли ответ на свой вопрос, то вы можете задать его через форму обратной связи. Пожалуйста, опишите возникшую проблему как можно подробнее. Если возможно, приложите скриншот.