Skip to main content

SDK push-уведомлений для Unity (версия 6.1.0)

Условия корректной работы SDK

Условия работы push-уведомлений:

  • Используется актуальная версия SDK.
  • Приложение загружено в Консоль RuStore.
  • Приложение прошло модерацию (публиковать приложение необязательно).
  • На устройстве пользователя установлена актуальная версия RuStore.
  • Приложение RuStore поддерживает функциональность push-уведомлений.
  • Приложению RuStore разрешен доступ к работе в фоновом режиме. Без этого разрешения push-уведомления будут приходить, но со значительной задержкой.
  • Отпечаток подписи приложения, установленного на девайсе, совпадает с отпечатком подписи приложения, которое загружено в Консоль RuStore.

Пример реализации

Ознакомьтесь с приложением-примером, чтобы узнать, как правильно интегрировать SDK push-уведомлений.

Подключение в проект

Для подключения скачайте RuStore Push SDK и импортируйте его в проект (Assets > Import Package > Custom Package). Зависимости подключаются автоматически с помощью External Dependency Manager (включен в SDK).

tip

Если вы используете операционную систему macOS, измените настройки утилиты архивации. В настройках Archive Utility снимите флажок Keep expanding if possible. В противном случае архив проекта будет скачан некорректно.

Также вы можете склонировать код с помощью Git.

Для корректной обработки зависимостей SDK выполните следующие настройки:

  1. Откройте настройки проекта: Edit > Project Settings > Player > Android Settings.

  2. В pазделе Publishing Settings: включите настройки:

    • Custom Main Manifest.
    • Custom Main Gradle Template.
    • Custom Gradle Properties Template.
  3. В разделе Other Settings: настройте:

    • package name.
    • Minimum API Level = 24.
    • Target API Level = 34.
  4. Откройте настройки External Dependency Manager: Assets > External Dependency Manager > Android Resolver > Settings, включите настройки:

    • Use Jetifier.
    • Patch mainTemplate.gradle.
    • Patch gradleTemplate.properties.
  5. Обновите зависимости проекта: Assets > External Dependency Manager > Android Resolver > Force Resolve.

Обновление

Версии плагина 6.1.0 и выше содержат измененную структуру директорий. Измененная структура позволяет использовать преимущества раздельных сборок частей проекта Assembly definitions.

Перед установкой обновления выполните удаление папок:

  • Assets > RuStoreSDK > PushClient > Editor.
  • Assets > RuStoreSDK > Common > Editor.
img

После удаления импортируйте новый .unitypackage в проект как при обычной установке (Assets > Import Package > Custom Package).

Редактирование манифеста приложения

Объявите службу 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>

Если нужно изменить иконку или цвет стандартной нотификации, добавьте:

AndroidManifest.xml
<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" />

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

AndroidManifest.xml
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_channel_id"
android:value="@string/pushes_notification_channel_id" />

При добавлении канала push-уведомлений вы должны создать канал самостоятельно.

Чтобы иметь возможность перехода в приложение по тапу push-сообщение, вы должны сделать RuStoreUnityActivity основным активити. Для этого добавьте следующую запись в манифест вашего проекта:

<activity android:name="ru.rustore.unitysdk.RuStoreUnityActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Одновременно, вы должны удалить следующий <intent-filter> из активити com.unity3d.player.UnityPlayerActivity:

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Совместимость с другими плагинами

Класс RuStoreUnityActivity выполнит обработку Intents и запустит UnityPlayerActivity. Это необходимо, чтобы правильно обработать переход в приложение по тапу на пуш-уведомление.

Если вам необходимо изменить это поведение, модифицируйте файл RuStoreUnityActivity.java: RuStoreSDK > PushClient > Android заменив UnityPlayerActivity своим классом.

Запрос разрешения на показ уведомлений в Android 13+

В версии Android 13 появилось новое разрешение для отображения push-уведомлений. Это затронет все приложения, которые работают на Android 13 или выше и используют RuStore Push SDK.

По умолчанию RuStore Push SDK версии 1.4.0 и выше включает разрешение POST_NOTIFICATIONS, определённое в манифесте. Однако приложению также нужно запросить это разрешение во время выполнения через константу android.permission.POST_NOTIFICATIONS. Приложение сможет показывать push-уведомления, только когда пользователь предоставит на это разрешение.

Запрос разрешения на показ push-уведомлений:

Activity/Fragment
// 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 проекта».

img

Инициализация SDK push-уведомлений

Добавьте в AndroidManifest.xml следующий код:

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:

RuStorePushClientParamsExample.java
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-уведомлений, реализуйте в вашем наследнике RuStoreUnityPushClientParams метод getLogger. Метод getLogger должен возвращать объект реализующий интерфейс Logger.

Интерфейс 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)
}
}
Метод getLogger
@NonNull
@Override
public Logger getLogger() {
return UnityLogger("your_tag");
}

Если не передать Logger, SDK использует реализацию по умолчанию с AndroidLog.

Чтобы логировать события с использованием скриптинга Unity, используйте релизацию интерфеса ILogListener. Объект реализующий интерфейс должен быть передан в методе инициализации плагина.

Интерфейс 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:

RuStorePushClientParamsExample.java
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-токена пользователя

caution

Если у пользователя нет push-токена, метод создаст и вернёт новый push-токен.

После инициализации библиотеки вы можете использовать метод RuStorePushClient.getToken(), чтобы получить текущий push-токен пользователя.
Вызов метода GetToken
RuStorePushClient.Instance.GetToken(
onFailure: (error) => {
// Process error
},
onSuccess: (token) => {
// Process success
});

Удаление push-токена пользователя

После инициализации библиотеки вы можете использовать метод RuStorePushClient.deleteToken(), чтобы удалить текущий push-токен пользователя.
Вызов метода DeleteToken
RuStorePushClient.Instance.DeleteToken(
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
});

Методы для работы с push-топиком

Подписка на push-уведомления по топику

После инициализации библиотеки вы можете использовать метод SubscribeToTopic(your_topic_name) для подписки на топик.

Вызов метода SubscribeToTopic
RuStorePushClient.Instance.SubscribeToTopic(
topicName: "your_topic_name" ,
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
});

Отписка от push-уведомлений по топику

После инициализации библиотеки вы можете использовать метод UnsubscribeFromTopic(your_topic_name) для отписки от топика.

Вызов метода UnsubscribeFromTopic
RuStorePushClient.Instance.UnsubscribeFromTopic(
topicName: "your_topic_name" ,
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
});

Получение данных от RuStore SDK

Для получения и обработки данных push-уведомлений на стороне Unity реализуйте интерфейс IMessagingServiceListener. Объект реализующий интерфейс должен быть передан в методе инициализации плагина.

IMessagingServiceListener.cs
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);
}
}
Название методаОписание

onNewToken

Метод вызывается при получении нового push-токена. После вызова этого метода ваше приложение становится ответственно за передачу нового push-токена на свой сервер. Метод возвращает значение нового токена.

onMessageReceived

Метод вызывается при получении нового push-уведомления. < p/> Если в объекте notification есть данные, RuStore SDK самостоятельно отображает уведомление. Если вы не хотите этого, используйте объект data, а notification оставьте пустым. Метод вызывается в любом случае. < p/> Получить payload push-уведомления Dictionary<string, string> можно из поля message.data.

DeletedMessagesResponse

Метод вызывается, если один или несколько push-уведомлений не доставлены на устройство. Например, если время жизни уведомления истекло до момента доставки. < p/> При вызове этого метода рекомендуется синхронизироваться со своим сервером, чтобы не пропустить данные.

ErrorResponse

Метод вызывается, если в момент инициализации возникает ошибка. Он возвращает массив объектов с ошибками. < p/> Возможные ошибки:

  • UnauthorizedException — пользователь не авторизован в RuStore.
  • HostAppNotInstalledException — RuStore отсутствует на устройстве пользователя.
  • HostAppBackgroundWorkPermissionNotGranted — у RuStore нет разрешения на работу в фоне.
Все возможные ошибки описаны в разделе Обработка ошибок.

Структура уведомления

Структура полного уведомления
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 — возвращает значение приоритетности (на данный момент не учитывается). Сейчас заложены следующие варианты:
    • 0UNKNOWN.
    • 1HIGH.
    • 2NORMAL.

  • ttl — время жизни push-уведомления типа Int в секундах.
  • from — поле, по которому можно понять, откуда пришло уведомление:
    • Для уведомлений, отправленных в топик, в поле отображается имя топика.
    • В других случаях — часть вашего сервисного токена.
  • collapseKey — идентификатор группы уведомлений (на данный момент не учитывается).
  • data — словарь, в который можно передать дополнительные данные для уведомления.
  • rawData — словарь data в виде массива байтов.
  • notification — объект уведомления.
Структура объекта 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;
public ClickActionType? clickActionType;
}
  • 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.
  • clickActionintent action, с помощью которого будет открыта активити при клике на уведомление.
  • clickActionType — тип поля clickAction.
Перечисление ClickActionType
namespace RuStore.PushClient
{
public enum ClickActionType
{
DEFAULT,
DEEP_LINK,
}
}

Создание канала для отправки уведомления

Для канала, в который отправляется уведомление, действует следующий приоритет:

  • Если в push-уведомлении есть поле channelId, RuStore SDK отправит уведомление в указанный канал. Ваше приложение должно создать этот канал заранее.

  • Если в push-уведомлении нет поля channelId, но ваше приложение указало параметр с каналом в AndroidManifest.xml, используется указанный канал. Ваше приложение должно создать этот канал заранее.

  • Если в push-уведомлении нет поля channelId, и канал по умолчанию не задан в AndroidManifest.xml, RuStore SDK создаст канал и отправит уведомление в него. В дальнейшем все уведомления без явного указания канала будут отправляться в этот канал.

Обработка ошибок

Если вы получили в ответ Failure, не рекомендуется отображать ошибку пользователю. Отображение ошибки может негативно повлиять на пользовательский опыт.

Класс RuStoreError
namespace RuStore {

public class RuStoreError {

public string name;
public string description;
}
}
  • name — название ошибки. Содержит имя simpleName класса ошибки.
  • description — сообщение ошибки.

Если при инициализации SDK вы передали параметр allowNativeErrorHandling == true, в случае ошибки:

  • Вызовется соответствующий обработчик onFailure.

  • Ошибка передастся в метод resolveForPush нативного SDK. Это нужно, чтобы показать пользователю диалог с ошибкой.

Метод resolveForPush
fun RuStoreException.resolveForPush(context: Context)

Чтобы отключить передачу ошибки в нативный SDK, установите значение false для свойства AllowNativeErrorHandling.

Запрет нативной обработки ошибок
RuStorePushClient.Instance.AllowNativeErrorHandling = false;

Возможные ошибки

  • RuStoreNotInstalledException — на устройстве пользователя не установлен RuStore.

  • RuStoreOutdatedException — версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK.

  • RuStoreUserUnauthorizedException — пользователь не авторизован в RuStore.

  • RuStoreFeatureUnavailableException — RuStore не имеет разрешения на работу в фоне.

  • RuStoreException — базовая ошибка RuStore, от которой наследуются остальные ошибки.

См. также