SDK push-уведомлений для Unity (версия 1.4.0)
Условия корректной работы SDK
Ниже перечислены условия работы push-ув едомлений.
- Подпись тестируемой сборки (например,
debug
) приложения должна совпадать с подписью сборки приложения, которая была загружена в консоль и прошла модерацию ранее (например,release
).
- Используется актуальная версия SDK.
- Приложение загружено в Консоль RuStore.
- Приложение прошло модерацию (публиковать приложение необязательно).
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность push-уведомлений.
- Приложению RuStore разрешен доступ к работе в фоновом режиме. Без этого разрешения push-уведомления будут приходить, но со значительной задержкой.
- Отпечаток подписи приложения, установленного на девайсе, совпадает с отпеч атком подписи приложения, которое загружено в Консоль RuStore.
Пример реализации
Ознакомьтесь с приложением-примером, чтобы узнать, как правильно интегрировать SDK push-уведомлений.
Подключение в проект
Для подключения скачайте RuStore Push SDK и импортируйте его в проект (Assets > Import Package > Custom Package). Зависимости подключаются автоматически с помощью External Dependency Manager (включен в SDK).
Если вы используете операционную систему macOS, измените настройки утилиты архивации. В настройках Archive Utility снимите флажок Keep expanding if possible. В противном случае архив проекта будет скачан некорректно.
Также вы можете склонировать код с помощью Git.
Для корректной обработки зависимостей SDK выполните следующие настройки.
-
Откройте настройки проекта: Edit > Project Settings > Player > Android Settings.
-
В pазделе Publishing Settings включите следующие настройки.
- Custom Main Manifest.
- Custom Main Gradle Template.
- Custom Gradle Properties Template.
-
В разделе Other Settings настройте:
- package name.
- Minimum API Level = 24.
- Target API Level = 34.
-
Откройте настройки External Dependency Manager: Assets > External Dependency Manager > Android Resolver > Settings, включите следующие настройки.
- Use Jetifier.
- Patch mainTemplate.gradle.
- Patch gradleTemplate.properties.
-
Обновите зависимости проекта: Assets > External Dependency Manager > Android Resolver > Force Resolve.
Редактирование манифеста приложения
Объявите службу RuStoreUnityMessagingService
.
<service
android:name="ru.rustore.unitysdk.pushclient.RuStoreUnityMessagingService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="ru.rustore.sdk.pushclient.MESSAGING_EVENT" />
</intent-filter>
</service>
Если нужно изменить иконку или цвет стандартной нотификации, добавьте следующий код.
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_icon"
android:resource="@drawable/ic_baseline_android_24" />
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_color"
android:resource="@color/your_favorite_color" />
Если нужно переопределить канал уведомлений, добавьте следующий код.
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_channel_id"
android:value="@string/pushes_notification_channel_id" />
При добавлении канала push-уведомлений вы должны создать канал самостоятельно.
Запрос разрешения на показ уведомлений в Android 13+
В версии Android 13 появилось новое разрешение для отображения push-уведомлений. Это затронет все приложения, которые работают на Android 13 или выше и используют RuStore Push SDK.
По умолчанию RuStore Push SDK версии 1.4.0 и выше включает разрешение POST_NOTIFICATIONS
, определённое в манифесте.
Однако приложению также нужно запросить это разрешение во время выполнения через константу android.permission.POST_NOTIFICATIONS
.
Приложение сможет показывать push-уведомления, только когда пользователь предоставит на это разрешение.
Запрос разрешения на показ push-уведомлений.
// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
// RuStore Push SDK (and your app) can post notifications.
} else {
// TODO: Inform user that your app will not show notifications.
}
});
private void askNotificationPermission() {
// This is only necessary for API level>= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED) {
// RuStore Push SDK (and your app) can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// TODO: display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
}
}
Инициализация
Для инициализации понадобится идентификатор проекта из RuStore Консоль. Чтобы получить его, на странице приложения перейдите в раздел Push-уведомления > Проекты и скопируйте значение в поле ID проекта.
Инициализация SDK push-уведомлений
Добавьте в AndroidManifest.xml
следующий код.
<meta-data
android:name="ru.rustore.sdk.pushclient.project_id"
android:value="i5UTx96jw6c1C9LvdlE4cdNrWHMNyRBt" />
<meta-data
android:name="ru.rustore.sdk.pushclient.params_class"
android:value="ru.rustore.unitysdk.pushclient.RuStorePushClientParamsExample" />
projectId
— идентификатор проекта из RuStore Консоль. Чтобы получить его, на странице приложения перейдите в раздел Push-уведомления > Проекты и скопируйте значение в поле ID проекта.params_class
(опционально) — полное имя класса своей реализацииAbstractRuStorePushClientParams
. Параметр нужен для указания дополнительных параметров инициализации push-клиента.
Пример реализации RuStorePushClientParamsExample
.
package ru.rustore.unitysdk.pushclient;
import android.content.Context;
import com.vk.push.common.clientid.ClientId;
import com.vk.push.common.clientid.ClientIdCallback;
import com.vk.push.common.clientid.ClientIdType;
import ru.rustore.sdk.pushclient.common.logger.Logger;
import ru.rustore.sdk.pushclient.provider.AbstractRuStorePushClientParams;
public class RuStorePushClientParamsExample extends AbstractRuStorePushClientParams {
private boolean isTestModeEnabled;
public RuStorePushClientParamsExample(Context context) {
super(context);
int testMode = context.getResources().getIdentifier("rustore_PushClientSettings_testMode", "string", context.getPackageName());
isTestModeEnabled = context.getString(testMode).equalsIgnoreCase("true");
}
@Override
public Logger getLogger() {
return new UnityLogger("RuStoreUnityPushClient");
}
@Override
public boolean getTestModeEnabled() {
return isTestModeEnabled;
}
@Override
public ClientIdCallback getClientIdCallback() {
return () -> new ClientId("your_gaid_or_oaid", ClientIdType.GAID);
}
}
Инициализация плагина
Перед вызовом методов плагина необходимо создать объект клиента push-уведомлений RuStorePushClient
. Для инициализации клиента выполните метод init
.
public class Example : MonoBehaviour, IMessagingServiceListener, ILogListener {
private void Awake() {
var pushConfig = new RuStorePushClientConfig() {
messagingServiceListener = this,
logListener = this
};
RuStorePushClient.Instance.Init(pushConfig);
}
/* Реализация интерфейсов IMessagingServiceListener, ILogListener */
}
Логирование событий
Если вам не обходимо логировать события библиотеки push-уведомлений, реализуйте в вашем наследнике AbstractRuStorePushClientParams
метод getLogger
. Метод getLogger
должен возвращать объект реализующий интерфейс Logger
.
interface Logger {
fun verbose(message: String, throwable: Throwable? = null)
fun debug(message: String, throwable: Throwable? = null)
fun info(message: String, throwable: Throwable? = null)
fun warn(message: String, throwable: Throwable? = null)
fun error(message: String, throwable: Throwable? = null)
fun createLogger(tag: String): Logger
}
package ru.rustore.unitysdk.pushclient
import android.util.Log
import ru.rustore.sdk.pushclient.common.logger.Logger
class UnityLogger (
private val tag: String? = null,
) : Logger {
override fun verbose(message: String, throwable: Throwable?) {
Log.v(tag, message, throwable)
RuStoreUnityPushClient.Log("[V] $tag $message");
logException(throwable)
}
override fun debug(message: String, throwable: Throwable?) {
Log.d(tag, message, throwable)
RuStoreUnityPushClient.Log("[D] $tag $message");
logException(throwable)
}
override fun info(message: String, throwable: Throwable?) {
Log.i(tag, message, throwable)
RuStoreUnityPushClient.Log("[I] $tag $message");
logException(throwable)
}
override fun warn(message: String, throwable: Throwable?) {
Log.w(tag, message, throwable)
RuStoreUnityPushClient.LogWarning("[W] $tag $message");
logException(throwable)
}
override fun error(message: String, throwable: Throwable?) {
Log.e(tag, message, throwable)
RuStoreUnityPushClient.LogError("[E] $tag $message");
logException(throwable)
}
private fun logException(throwable: Throwable?) {
if (throwable != null) {
RuStoreUnityPushClient.LogException(throwable)
}
}
override fun createLogger(tag: String): Logger {
val newTag = if (this.tag != null) {
"${this.tag}:$tag"
} else {
tag
}
return UnityLogger(newTag)
}
}
@NonNull
@Override
public Logger getLogger() {
return UnityLogger("your_tag");
}
Если не передать Logger
, SDK использует реализацию по умолчанию с AndroidLog
.
Чтобы логировать события с использованием скриптинга Unity, используйте релизацию интерфеса ILogListener
. Объект реализующий интерфейс должен быть передан в методе инициализации плагина.
namespace RuStore.PushClient {
public interface ILogListener {
public void Log(string logString);
public void LogWarning(string logString);
public void LogError(string logString);
}
}
Работа с сегментами пользователей
Сегмент — это группа пользователей, которых вы выбираете по определенным параметрам. Например, пользователи, которые приносят наибольший доход, или пользователи со старой версией Android. Подробности о сегментах — в документации MyTracker.
Чтобы начать работу с сегментами, укажите ClientIdType
и ClientIdValue
при инициализации SDK.
public class RuStorePushClientParamsExample extends AbstractRuStorePushClientParams {
/* Реализация AbstractRuStorePushClientParams */
@Override
public ClientIdCallback getClientIdCallback() {
return () -> new ClientId("your_gaid_or_oaid", ClientIdType.GAID);
}
}
CLIENT_ID_VALUE
— значение идентификатора (your_gaid_or_oaid
).CLIENT_ID_TYPE
— тип идентификатора:ClientIdType.GAID
— рекламный идентификатор Google;ClientIdType.OAID
— рекламный идентификатор Huawei.
Проверка возможности получать push-уведомления
Для проверки того, что приложение RuStore установлено на устройстве пользователя, используйте методRuStorePushClient.checkPushAvailability
.
RuStorePushClient.Instance.CheckPushAvailability(
onFailure: (error) => {
// Process error
},
onSuccess: (response) => {
if (!response.isAvailable) {
// Process push unavailable
}
}
);
Методы для работы с push-токеном
Получение push-токена пользователя
Если у пользователя нет push-токена, метод создаст и вернёт новый push-токен.
RuStorePushClient.getToken()
, чтобы получить текущий push-токен пользователя.
RuStorePushClient.Instance.GetToken(
onFailure: (error) => {
// Process error
},
onSuccess: (token) => {
// Process success
}
);
Удаление push-токена пользователя
После инициализации библиотеки вы можете использовать методRuStorePushClient.deleteToken()
, чтобы удалить текущий push-токен пользователя.
RuStorePushClient.Instance.DeleteToken(
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
}
);
Методы для работы с push-топиком
Подписка на push-уведомления по топику
После инициализации библиотеки вы можете использовать методSubscribeToTopic(your_topic_name)
для подписки на топик.
RuStorePushClient.Instance.SubscribeToTopic(
topicName: "your_topic_name",
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
}
);
Отписка от push-уведомлений по топику
После инициализации библиотеки вы можете использовать методUnsubscribeFromTopic(your_topic_name)
для отписки от топика.
RuStorePushClient.Instance.UnsubscribeFromTopic(
topicName: "your_topic_name",
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
}
);
Получение данных от RuStore SDK
Для получения и обработки данных push-уведомлений на стороне Unity реализуйте интерфейс IMessagingServiceListener
. Объект реализующий интерфейс должен быть передан в методе инициализации плагина.
using System.Collections.Generic;
namespace RuStore.PushClient {
public interface IMessagingServiceListener {
public void OnNewToken(string token);
public void OnMessageReceived(RemoteMessage message);
public void OnDeletedMessages();
public void OnError(List<RuStoreError> errors);
}
}
Название метода | Описание |
---|---|
| Метод вызывается при получении нового push-токена. После вызова этого метода ваше приложение становится ответственно за передачу нового push-токена на свой сервер. Метод возвращает значение нового токена. |
| Метод вызывается при получении нового push-уведомления. Если в объекте Получить |
| Метод вызывается, если один или несколько push-уведомлений не доставлены на устройство. Например, если время жизни уведомления истекло до момента доставки. При вызове этого метода рекомендуется синхронизироваться со своим сервером, чтобы не пропустить данные. |
| Метод вызывается, если в момент инициализации возникает ошибка. Он возвращает массив объектов с ошибками. Возможные ошибки:
|
Структура уведомления
public class RemoteMessage {
public string collapseKey;
public Dictionary< string , string > data;
public string messageId;
public Notification notification;
public int priority;
public sbyte [] rawData;
public int ttl;
}
messageId
— уникальный ID сообщения. Является идентификатором каждого сообщения.-
priority
— возвращает значение приоритетности (на данный момент не учитывается). Сейчас заложены следующие варианты:0
—UNKNOWN
;1
—HIGH
;2
—NORMAL
.
ttl
— время жизни push-уведомления типаInt
в секундах.from
— поле, по которому можно понять, откуда пришло уведомление:- для уведомлений, отправленных в топик, в поле отображается имя топика;
- в других случаях — часть вашего сервисного токена.
collapseKey
— идентификатор группы уведомлений (на данный момент не учитывается).data
— словарь, в который можно передать дополнительные данные для уведомления.rawData
— словарьdata
в виде массива байтов.notification
— объект уведомления.
public class Notification {
public string title;
public string body;
public string channelId;
public string imageUrl;
public string color;
public string icon;
public string clickAction;
}
title
— заголовок уведомления.body
— тело уведомления.channelId
— возможность задать канал, в который отправится уведомление. Актуально для Android 8.0 и выше.imageUrl
— прямая ссылка на изображение для вставки в уведомление. Изображение должно быть не более 1 Мбайт.color
— цвет уведомления в HEX-формате, строкой. Например,#0077FF
.icon
— значок уведомления изres/drawable
в формате строки, которая совпадает с названием ресурса.
Например, вres/drawable
есть значокsmall_icon.xml
, который доступен в коде черезR.drawable.small_icon
.
Чтобы значок отображался в уведомлении, сервер должен указать в параметреicon
значениеsmall_icon
.clickAction
—intent action
, с помощью которого будет открыта активити при клике на уведомление.
Создание канала для отправки уведомления
Для канала, в который отправляется уведомление, действует следующий приоритет.
-
Если в push-уведомлении есть поле
channelId
, RuStore SDK отправит уведомление в указанный канал. Ваше приложение должно создать этот канал заранее. -
Если в push-уведомлении нет поля
channelId
, но ваше приложение указало параметр с каналом вAndroidManifest.xml
, используется указанный канал. Ваше приложение должно создать этот канал заранее. -
Если в push-уведомлении нет поля
channelId
, и канал по умолчанию не задан вAndroidManifest.xml
, RuStore SDK создаст канал и отправит уведомление в него. В дальнейшем все уведомления без явного указания канала будут отправляться в этот канал.
Обработка ошибок
Если вы получили в ответ Failure
, не рекомендуется отображать ошибку пользователю. Отображение ошибки может негативно повлиять на пользовательский опыт.
namespace RuStore {
public class RuStoreError {
public string name;
public string description;
}
}
name
— название ошибки. Содержит имяsimpleName
класса ошибки.description
— сообщение ошибки.
Если при инициализации SDK вы передали параметр allowNativeErrorHandling == true
, в случае ошибки:
-
Вызовется соответствующий обработчик
onFailure
. -
Ошибка передастся в метод
resolveForPush
нативного SDK. Это нужно, чтобы показать пользователю диалог с ошибкой.
fun RuStoreException.resolveForPush(context: Context)
Чтобы отключить передачу ошибки в нативный SDK, установите значение false
для свойства AllowNativeErrorHandling
.
RuStorePushClient.Instance.AllowNativeErrorHandling = false;
Возможные ошибки
-
RuStoreNotInstalledException
— на устройстве пользователя не установлен RuStore. -
RuStoreOutdatedException
— версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK. -
RuStoreUserUnauthorizedException
— пользователь не авторизован в RuStore. -
RuStoreFeatureUnavailableException
— RuStore не имеет разрешения на работу в фоне. -
RuStoreException
— базовая ошибка RuStore, от которой наследуются остальные ошибки.