Конфигурация mSDK
Предварительные условия
- В приложении добавлен класс, расширяющий Application.
- В проекте должен быть подключён репозиторий Maven Central.
- Добавлена зависимость библиотеки в файл
build.gradle.kts
уровня приложения (app level):
dependencies {
implementation("com.altcraft:android-sdk:0.0.1")
}
Подготовка приложения
Настройка JWT-интерфейса (опционально)
JWTInterface — интерфейс запроса JWT-токена. Предоставляет актуальный JWT-токен из приложения по запросу SDK. Реализация данного интерфейса требуется, если используется JWT-аутентификация API-запросов. JWT подтверждает, что пользовательские идентификаторы аутентифицированы приложением.
Реализация JWT-аутентификации обязательна, если используется тип матчинга отличный от push-данных из подписки (например, идентификатор пользователя — email или телефон).
Интерфейс SDK:
interface JWTInterface {
fun getJWT(): String?
}
Реализация на стороне приложения
import android.content.Context
import com.altcraft.sdk.interfaces.JWTInterface
class JWTProvider(): JWTInterface {
override fun getJWT(): String? {
// code that returns the current JWT token
}
}
Регистрация провайдера в Application.onCreate()
import android.app.Application
import com.altcraft.sdk.AltcraftSDK
class App : Application() {
override fun onCreate() {
super.onCreate()
AltcraftSDK.setJWTProvider(JWTProvider(applicationContext))
}
}
getJWT()
— синхронная функция. Поток выполнения SDK будет приостановлен до получения JWT. Рекомендуется, чтобы getJWT()
возвращал значение немедленно — из кэша (in-memory, SharedPreferences
или EncryptedSharedPreferences
) — это ускорит выполнение запросов. Желательно подготовить актуальный JWT как можно раньше (на старте приложения) и сохранить его в кэш, чтобы при обращении SDK токен был доступен без задержек. При отсутствии значения допустимо вернуть null
.
Подготовка к работе с push-провайдерами
Для предварительной подготовки приложения к работе в провайдерами push, необходимо:
- Интегрировать SDK push-провайдеров в проект;
- Реализовать интерфейсы SDK для передачи и удаления push-токена;
- Расширить сервисы push-провайдеров;
- Зарегистрировать сервис push-провайдера в
AndroidManifest.xml
.
Firebase Cloud Messaging
Интеграция FCM SDK в проект
ССЫЛКА НА ДОКУМЕНТАЦИЮ
Реализация интерфейса Altcraft SDK
FCMInterface — интерфейс запроса и удаления push-токена FCM:
- Передает токен FCM в SDK Altcraft
- Удаляет токен FCM по запросу SDK Altcraft
Интерфейс SDK:
interface FCMInterface {
suspend fun getToken(): String?
suspend fun deleteToken(completion: (Boolean) -> Unit)
}
Рекомендуемая реализация на стороне приложения
import com.altcraft.sdk.interfaces.FCMInterface
import com.google.firebase.Firebase
import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.messaging
import kotlinx.coroutines.tasks.await
class FCMProvider : FCMInterface {
override suspend fun getToken(): String? = try {
Firebase.messaging.token.await()
} catch (_: Exception) {
null
}
override suspend fun deleteToken(completion: (Boolean) -> Unit) {
try {
FirebaseMessaging.getInstance().deleteToken().addOnCompleteListener {
completion(it.isSuccessful)
}
} catch (_: Exception) {
completion(false)
}
}
}
Регистрация провайдера в Application.onCreate()
import android.app.Application
class App : Application() {
override fun onCreate() {
super.onCreate()
AltcraftSDK.pushTokenFunctions.setFCMTokenProvider(FCMProvider())
}
}
Расширение сервиса провайдера
Рекомендуемая реализация FCMService
с передачей уведомления в функцию takePush()
:
import com.altcraft.sdk.AltcraftSDK
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
/**
* FCM service for handling push tokens and messages.
*/
class FCMService : FirebaseMessagingService() {
/**
* Called when a new FCM token is generated.
*
* @param token The new FCM token.
*/
override fun onNewToken(token: String) {
super.onNewToken(token)
}
/**
* Called when a push message is received.
*
* @param message The received [RemoteMessage].
*/
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
AltcraftSDK.PushReceiver.takePush(this@FCMService, message.data)
}
}
Регистрация сервиса push-провайдера в AndroidManifest.xml
<service
android:name="<your_package_name>.FCMService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Huawei Mobile Services
Интеграция HMS SDK в проект
ССЫЛКА НА ДОКУМЕНТАЦИЮ
Реализация интерфейса Altcraft SDK
HMSInterface — интерфейс запроса и удаления push-токена HMS.
Интерфейс SDK:
import android.content.Context
interface HMSInterface {
suspend fun getToken(context: Context): String?
suspend fun deleteToken(context: Context, complete: (Boolean) -> Unit)
}
Рекомендуемая реализация на стороне приложения
import android.content.Context
import com.altcraft.sdk.interfaces.HMSInterface
import com.huawei.agconnect.AGConnectOptionsBuilder
import com.huawei.hms.aaid.HmsInstanceId
import com.huawei.hms.api.HuaweiApiAvailability
private const val APP_ID = "client/app_id"
private const val TOKEN_SCOPE = "HCM"
class HMSProvider : HMSInterface {
override suspend fun getToken(context: Context): String? = try {
val availability = HuaweiApiAvailability.getInstance()
.isHuaweiMobileServicesAvailable(context)
if (availability != com.huawei.hms.api.ConnectionResult.SUCCESS) return null
val appId = AGConnectOptionsBuilder().build(context).getString(APP_ID)
HmsInstanceId.getInstance(context).getToken(appId, TOKEN_SCOPE)
} catch (e: Exception) {
null
}
override suspend fun deleteToken(context: Context, complete: (Boolean) -> Unit) {
try {
val appId = AGConnectOptionsBuilder().build(context).getString(APP_ID)
HmsInstanceId.getInstance(context).deleteToken(appId, TOKEN_SCOPE)
complete(true)
} catch (e: Exception) {
complete(false)
}
}
}
Регистрация провайдера в Application.onCreate()
import android.app.Application
class App : Application() {
override fun onCreate() {
super.onCreate()
AltcraftSDK.pushTokenFunctions.setHMSTokenProvider(HMSProvider())
}
}
Расширение сервиса провайдера
Рекомендуемая реализация HMSService
с передачей уведомления в функцию takePush()
:
import com.altcraft.sdk.AltcraftSDK
import com.huawei.hms.push.HmsMessageService
import com.huawei.hms.push.RemoteMessage
/**
* HMS service for handling push tokens and incoming notifications.
*
* Extends [HmsMessageService] and overrides key HMS callback methods.
*/
class HMSService : HmsMessageService() {
/**
* Called when a new HMS token is generated.
*
* @param token The new HMS token.
*/
override fun onNewToken(token: String) {
super.onNewToken(token)
}
/**
* Called when a push message is received from HMS.
*
* Forwards the message with additional metadata to all receivers.
*
* @param message The received [RemoteMessage].
*/
override fun onMessageReceived(message: RemoteMessage) {
AltcraftSDK.PushReceiver.takePush(this@HMSService, message.dataOfMap)
}
}
Регистрация сервиса push-провайдера в AndroidManifest.xml
<service
android:name="<your_package_name>.HMSService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
RuStore
Интеграция RuStore SDK в проект
ССЫЛКА НА ДОКУМЕНТАЦИЮ
Реализация интерфейса Altcraft SDK
RustoreInterface — интерфейс запроса и удаления push-токена RuStore.
Интерфейс SDK:
interface RustoreInterface {
suspend fun getToken(): String?
suspend fun deleteToken(complete: (Boolean) -> Unit)
}
Рекомендуемая реализация на стороне приложения
import com.altcraft.sdk.interfaces.RustoreInterface
import kotlinx.coroutines.CompletableDeferred
import ru.rustore.sdk.core.feature.model.FeatureAvailabilityResult
import ru.rustore.sdk.pushclient.RuStorePushClient
class RuStoreProvider : RustoreInterface {
override suspend fun getToken(): String? {
val deferred = CompletableDeferred<String?>()
try {
val token = RuStorePushClient.getToken().await()
RuStorePushClient.checkPushAvailability()
.addOnSuccessListener { result ->
when (result) {
FeatureAvailabilityResult.Available -> deferred.complete(token)
is FeatureAvailabilityResult.Unavailable -> deferred.complete(null)
}
}
.addOnFailureListener { deferred.complete(null) }
} catch (e: Exception) {
return null
}
return deferred.await()
}
override suspend fun deleteToken(complete: (Boolean) -> Unit) {
try {
RuStorePushClient.deleteToken()
.addOnSuccessListener { complete(true) }
.addOnFailureListener { complete(false) }
} catch (e: Exception) {
complete(false)
}
}
}
Регистрация провайдера в Application.onCreate()
import android.app.Application
class App : Application() {
override fun onCreate() {
super.onCreate()
AltcraftSDK.pushTokenFunctions.setRuStoreTokenProvider(RuStoreProvider())
}
}
Расширение сервиса провайдера
Рекомендуемая реализация RuStoreService
с передачей уведомления в функцию takePush()
:
import com.altcraft.sdk.AltcraftSDK
import ru.rustore.sdk.pushclient.messaging.model.RemoteMessage
import ru.rustore.sdk.pushclient.messaging.service.RuStoreMessagingService
/**
* RuStore service for handling push notifications.
*
* Extends [RuStoreMessagingService] and overrides key callbacks.
*/
class RuStoreService : RuStoreMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
}
/**
* Called when a push message is received.
*
* Forwards the message to all receivers with added metadata.
*
* @param message The received RemoteMessage.
*/
override fun onMessageReceived(message: RemoteMessage) {
AltcraftSDK.PushReceiver.takePush(this, message.data)
}
}
Регистрация сервиса push-провайдера в AndroidManifest.xml
<service
android:name="<your_package_name>.RuStoreService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="ru.rustore.sdk.pushclient.MESSAGING_EVENT" />
</intent-filter>
</service>
Инициализация SDK
Параметры инициализации
Для передачи параметров конфигурации используется класс AltcraftConfiguration
:
class AltcraftConfiguration private constructor(
private val apiUrl: String,
private val icon: Int? = null,
private val rToken: String? = null,
private val usingService: Boolean = false,
private val serviceMessage: String? = null,
private val appInfo: DataClasses.AppInfo? = null,
private val providerPriorityList: List<String>? = null,
private val pushReceiverModules: List<String>? = null,
private val pushChannelName: String? = null,
private val pushChannelDescription: String? = null
)
Описание параметров:
apiUrl String
Обязательный: Да
Описание: URL конечной точки Altcraft API
icon Int?
По умолчанию: null
Обязательный: Нет
Описание: Иде нтификатор ресурса drawable
, используемого как иконка уведомлений
rToken String?
По умолчанию: null
Обязательный: Нет
Описание: Ролевой токен Altcraft (идентифицирует ресурс, БД или аккаунт). Используется, если единственный тип матчинга — push-токен устройства, выданный провайдером.
usingService Boolean
По умолчанию: false
Обязательный: Нет
Описание: Включает использование foreground-сервисов при оформлении подписки и обновлении push-токена. Дает до ~1 минуты гарантированного сетевого окна даже при сворачивании/закрытии приложения (Android-требование: показывать уведомление сервиса). В большинстве случаев не обязателен, но полезен при нестабильной сети.
serviceMessage String?
По умолчанию: null
Обязательный: Нет
Описание: Текст уведомления foreground-сервисов и задач WorkManager
(если null
, то будет указано "background process"
). Рекомендуется задать явно — уведомления могут отображаться в фоне при обработке контента push.
appInfo DataClasses.AppInfo?
По умолчанию: null
Обязательный: Нет
Описание: Базовые метаданные приложения для Firebase Analytics. Для установки используйте публичный data-класс SDK AppInfo
(пакет com.altcraft.sdk.data.DataClasses
):
data class AppInfo(
/** Firebase app_id */
val appID: String,
/** Firebase app_instance_id */
val appIID: String,
/** Firebase app_version */
val appVer: String
)
providerPriorityList List<String>?
По умолчанию: null
Обязательный: Нет
Описание: Список приоритетов провайдеров. Используется для автоматического обновления push-токена подписки, если токен более приоритетного провайдера недоступен. Приоритет определяется индексом в списке: элемент с индексом 0 — самый приоритетный.
Пример использования:
providerPriorityList = listOf(
"android-firebase",
"android-huawei",
"android-rustore"
)
При такой настройке:
- SDK сначала запросит токен FCM; если FCM недоступен — HMS; если HMS недоступен — RuStore;
- Работает при условии, если в приложении реализованы интерфейсы соответствующих провайдеров.
Для удобства установки значения параметра SDK содержит публичные константы:
const val FCM_PROVIDER: String = "android-firebase"
const val HMS_PROVIDER: String = "android-huawei"
const val RUS_PROVIDER: String = "android-rustore"
Если значение не задано, приоритет провайдеров следующий:
FCM_PROVIDER → HMS_PROVIDER → RUS_PROVIDER
Значение параметра может содержать один элемент — в этом случае будет использоваться только один провайдер, независимо от доступности push-токена.
Параметр можно не указывать, если:
- в проекте используется только один провайдер;
- приоритет по умолчанию соответствует требованиям.
Кейс 1. Приоритет RUS_PROVIDER → FCM_PROVIDER
. Пользователь удаляет RuStore — уведомления RuStore недоступны. При рекомендованной реализации RustoreInterface.getToken()
вернёт null
, SDK автоматически переключится на FCM, обновит токен подписки, коммуникации сохранятся.
Кейс 2. Параметр не задан, действуют значения по умолчанию FCM_PROVIDER → HMS_PROVIDER → RUS_PROVIDER
. На устройстве Huawei без Google-сервисов SDK автоматически перейдёт на HMS без дополнительного кода.
pushReceiverModules List<String>?
По умолчанию: null
Обязательный: Нет
Описание: Cписок имён пакетов, в которых находятся реализации AltcraftPushReceiver : AltcraftSDK.PushReceiver()
.
Если указан, SDK обнаружит эти классы и передаст им входящее уведомление (через pushHandler(context: Context, message: Map<String, String>)
). Если классы не найдены ни в одном из пакетов, уведомление будет показано средствами SDK.
Пример создания класса AltcraftPushReceiver
package com.altcraft.altcraftmobile.test
import android.content.Context
import androidx.annotation.Keep
import com.altcraft.sdk.AltcraftSDK
@Keep
class AltcraftPushReceiver: AltcraftSDK.PushReceiver() {
override fun pushHandler(context: Context, message: Map<String, String>) {
//handle the notification using the SDK functions
super.pushHandler(context, message)
//additional notification-handling logic
}
}
Кейс: Приложение содержит несколько модулей, в которых необходимы данные входящих push-уведомлений Altcraft. В каждом из этих модулей можно создать класс AltcraftPushReceiver: AltcraftSDK.PushReceiver()
и получить входящее push-уведомление как message: Map<String, String>
.
Обратите внимание, что класс обязательно должен называться AltcraftPushReceiver
.
Если в проекте есть только один класс AltcraftPushReceiver
, внутри метода pushHandler
необходимо вызвать super.pushHandler(context, message)
, чтобы уведомление корректно обработалось средствами SDK. При наличии нескольких таких классов вызов super.pushHandler
нужно оставить лишь в одном из них — иначе каждое уведомление будет продублировано. Если же вы хотите полностью контролировать обработку push-уведомлений самостоятельно, вызов super.pushHandler
можно опустить.
pushChannelName String?
По умолчанию: null
Обязательный: Нет
Описание: Базовое имя канала push-уведомлений (видно в настройках Android). В зависимости от настроек звука и вибрации push-шаблона в платформе Altcraft к имени добавляется суффикс:
allSignal
— звук и вибрация включены;soundless
— бесшумный канал;onlySound
— только звук (без вибрации).
Пример: при pushChannelName = "Altcraft"
и режиме allSignal
видимое имя канала — "Altcraft_allSignal"
. Если параметр не указан — SDK использует имена по умолчанию: "allSignal"
, "soundless"
, "onlySound"
.
pushChannelDescription String?
По умолчанию: null
Обяз ательный: Нет
Описание: Описание push-канала (видно в настройках Android). К описанию добавляется режим уведомления:
Vibration and sound enabled
;Vibration and sound disabled
;Sound enabled, vibration disabled
.
Пример: "Altcraft notification channel. (vibration and sound enabled)"
.
Если параметр не указан — SDK использует значения по умолчанию:
- icon —
altcraft-sdk/src/main/res/drawable/icon.xml
(если icon = null); - serviceMessage —
"background process"
(если serviceMessage = null); - providerPriorityList —
FCM_PROVIDER → HMS_PROVIDER → RUS_PROVIDER
(если null); - pushChannelName —
"allSignal", "soundless", "onlySound"
(если null); - pushChannelDescription —
"Vibration and sound enabled", "Vibration and sound disabled", "Sound enabled, vibration disabled"
(если null).
Выполнение инициализации
Вызывайте AltcraftSDK.initialization(...)
тогда, когда это необходимо, но только после регистрации всех провайдеров (JWT-провайдера и провайдеров push-токенов). Запросы следует выполнять после установки конфигурации.
Для инициализации SDK используется функция fun initialization(context: Context, configuration: AltcraftConfiguration, complete: ((Result<Unit>) -> Unit)? = null)
:
// SDK initialization and configuration setup
AltcraftSDK.initialization(
context = context,
configuration = config,
complete = null // optional
)
Пример правильного порядка инициализации в Application.onCreate()
(после регистрации провайдеров)
import android.app.Application
import com.altcraft.sdk.AltcraftSDK
import com.altcraft.sdk.config.AltcraftConfiguration
import com.altcraft.sdk.data.DataClasses
import com.altcraft.fcm.FCMProvider
import com.altcraft.hms.HMSProvider
import com.altcraft.rustore.RuStoreProvider
import ru.rustore.sdk.pushclient.RuStorePushClient
class App : Application() {
override fun onCreate() {
super.onCreate()
// Rustore provider SDK initialization (if it's used)
RuStorePushClient.init(this, "rustore-project-id-1234")
// Provider registration before SDK initialization
AltcraftSDK.setJWTProvider(JWTProvider(applicationContext))
AltcraftSDK.pushTokenFunctions.setFCMTokenProvider(FCMProvider())
AltcraftSDK.pushTokenFunctions.setHMSTokenProvider(HMSProvider())
AltcraftSDK.pushTokenFunctions.setRuStoreTokenProvider(RuStoreProvider())
// SDK configuration
val config = AltcraftConfiguration.Builder(
apiUrl = "https://pxl-example.altcraft.com",
icon = R.drawable.ic_notification
).build()
// Initialization
AltcraftSDK.initialization(this, config)
}
}
Пример минимальной рабочей настройки
val config = AltcraftConfiguration.Builder(
apiUrl = "https://pxl-example.altcraft.com"
).build()
AltcraftSDK.initialization(context, config)
Пример настройки всех параметров
val config = AltcraftConfiguration.Builder(
apiUrl = "https://pxl-example.altcraft.com",
icon = R.drawable.ic_notification,
rToken = null,
usingService = true,
serviceMessage = "Processing Altcraft operations…",
appInfo = DataClasses.AppInfo(
appID = "com.example.app",
appIID = "8b91f3a0-1111-2222-3333-c1a2c1a2c1a2",
appVer = "1.0.0"
),
providerPriorityList = listOf(
FCM_PROVIDER, // "android-firebase"
HMS_PROVIDER, // "android-huawei"
RUS_PROVIDER // "android-rustore"
),
pushReceiverModules = listOf(
context.packageName,
"com.example.push_receiver",
"com.example.feature.test"
),
pushChannelName = "Altcraft",
pushChannelDescription = "Altcraft notifications channel"
).build()
AltcraftSDK.initialization(context, config)
Пример инициализации с callback завершения
AltcraftSDK.initialization(context, config) { result ->
when {
result.isSuccess -> {
// actions if initialization is succeed
}
result.isFailure -> {
// initialization error handling
}
}
}