Apps Kit SDK logoApps Kit SDK
Документация · AppsKitSDK (AKS) — Руководство по интеграции для Android

9. Локальные уведомления (AppsKitSDKLocalNotificationManager)

AKS предоставляет небольшой набор инструментов для локальных уведомлений: очередь, конструктор уведомлений и абстрактный BroadcastReceiver. С их помощью можно показывать собственные локальные уведомления. AKS не регистрирует ресивер в своём манифесте и не настраивает расписание — и то и другое нужно сделать самостоятельно.

9.1 Манифест

Создайте подкласс AppsKitSDKLocalNotificationBroadCastReceiver (см. §9.2) и объявите его как <receiver> внутри того же элемента <application>, который описан в §2:

xml
<application
    android:name=".YourApplication">

    <receiver
        android:name=".YourNotificationReceiver"
        android:exported="false" />

</application>

Если приложение нацелено на Android 13+ (API 33), также добавьте разрешение на отправку уведомлений, запрашиваемое во время выполнения. В манифесте AKS оно не объявлено, поэтому при слиянии манифестов автоматически не добавится:

xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

POST_NOTIFICATIONS — это разрешение, запрашиваемое во время выполнения, поэтому перед отправкой уведомлений его нужно запросить у пользователя (например, через ActivityResultContracts.RequestPermission()).

9.2 Добавление уведомления в очередь

Создайте подкласс AppsKitSDKLocalNotificationBroadCastReceiver и реализуйте checkNotifications(). Этот метод вызывается при каждом срабатывании ресивера: в нём вы определяете, пора ли показывать уведомление.

kotlin
class YourNotificationReceiver : AppsKitSDKLocalNotificationBroadCastReceiver() {

    override fun checkNotifications() {
        addNotificationInQueue(
            NotificationModel(
                id = "daily_reminder",                      // dedup key — a second add with the same id is ignored
                title = "Come back!",
                description = "You have unfinished items waiting.",
                icon = R.drawable.ic_notification,
                notificationId = 1001,                       // the actual Android notification ID passed to notify()
                targetScreen = "com.yourapp.MainActivity"    // fully-qualified Activity class opened on tap
            )
        )
    }
}

Сразу после завершения checkNotifications() метод onReceive автоматически вызывает AppsKitSDKLocalNotificationManager.showNotification(context): он извлекает из очереди самый старый NotificationModel и показывает уведомление. При таком подходе самостоятельно вызывать showNotification не нужно — достаточно добавить уведомление в очередь внутри checkNotifications().

При показе из очереди наличие разрешения POST_NOTIFICATIONS на Android 13+ проверяется автоматически. Если оно не выдано, показ пропускается без ошибки, но с записью в лог. Поэтому сначала запросите разрешение, как описано в §9.1.

9.3 Настройка расписания

AKS не регистрирует этот ресивер и не запускает его по расписанию. Вы сами определяете, когда срабатывает onReceive, обычно с помощью AlarmManager:

kotlin
val intent = Intent(context, YourNotificationReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    context, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setRepeating(
    AlarmManager.RTC_WAKEUP,
    System.currentTimeMillis() + intervalMs,
    intervalMs,
    pendingIntent
)

Для intervalMs можно задать фиксированный интервал в коде или использовать значение из удалённой конфигурации на портале AKS (HOURS_TO_MAKE_NOTIFICATION; если не задано, по умолчанию используется 2 часа). Это значение доступно через getTimeIntervalInMilliSeconds() в базовом классе ресивера, но метод объявлен как protected, поэтому вызывайте его внутри своего подкласса, а не напрямую в приведённом выше коде:

kotlin
class YourNotificationReceiver : AppsKitSDKLocalNotificationBroadCastReceiver() {
    fun intervalMillis(): Long = getTimeIntervalInMilliSeconds()
    override fun checkNotifications() { /* ... */ }
}

В режиме Doze и при оптимизации энергопотребления AlarmManager.setRepeating не гарантирует точное время срабатывания. Если нужен надёжный запуск, когда устройство неактивно, при каждом срабатывании планируйте следующий запуск через setExactAndAllowWhileIdle или используйте PeriodicWorkRequest из WorkManager (минимальный интервал — 15 минут). AKS не навязывает ни один из этих вариантов — выбирайте подходящий для вашего приложения. Также учтите, что запланированные срабатывания не сохраняются после перезагрузки устройства: их нужно регистрировать заново самостоятельно, например в ресивере BOOT_COMPLETED.

9.4 Прямой показ уведомления (без очереди)

Чтобы сразу показать уведомление, не используя описанную выше схему с очередью и ресивером:

kotlin
// Tapping opens the Activity at classPath
AppsKitSDKLocalNotificationManager.showNotification(
    context = this,
    id = 2001,
    classPath = "com.yourapp.MainActivity",
    channelId = "general",
    title = "New message",
    message = "You've got a new message waiting.",
    notificationIcon = R.drawable.ic_notification
)

// Or pass a fully-built Intent instead of a class path
AppsKitSDKLocalNotificationManager.showNotification(
    context = this,
    id = 2002,
    intent = Intent(this, MainActivity::class.java).putExtra("from", "notification"),
    channelId = "general",
    title = "New message",
    message = "Tap to view details.",
    notificationIcon = R.drawable.ic_notification
)

Обе перегрузки автоматически создают канал уведомлений, если он ещё не существует. В отличие от показа через очередь в §9.2, ни одна из них не проверяет POST_NOTIFICATIONS. На Android 13+ самостоятельно запросите разрешение во время выполнения, иначе вызов может завершиться без ошибки, но уведомление не появится.