9. 本地通知 (AppsKitSDKLocalNotificationManager)
AKS 提供了一套轻量级本地通知工具,包括队列、通知构建器和抽象 BroadcastReceiver,可用于显示你自己的本地通知。AKS 不会在其清单文件中注册该接收器,也不会为你调度通知;这两项都需要你自行处理。
9.1 清单配置
创建 AppsKitSDKLocalNotificationBroadCastReceiver 的子类(见 §9.2),并将该子类声明为 <receiver>,合并到 §2 中的同一个 <application> 元素内:
<application
android:name=".YourApplication">
<receiver
android:name=".YourNotificationReceiver"
android:exported="false" />
</application>如果应用以 Android 13+(API 33)为目标平台,还需要添加通知运行时权限。AKS 自身的清单文件未声明此权限,因此不会自动合并到你的应用中:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />POST_NOTIFICATIONS 是运行时权限,因此你仍需向用户请求授权(例如通过 ActivityResultContracts.RequestPermission()),之后才能实际发送通知。
9.2 将通知加入队列
创建 AppsKitSDKLocalNotificationBroadCastReceiver 的子类并实现 checkNotifications()。每次接收器被触发时,都会调用此方法,你可以在其中判断是否到了发送通知的时间:
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() 中将通知加入队列即可。
此队列通知显示流程会在 Android 13+ 上自行检查
POST_NOTIFICATIONS权限;如果未获授权,则会静默跳过(并记录一行日志)。因此,请务必先按照 §9.1 请求权限。
9.3 调度
AKS 不会注册此接收器,也不会按任何时间计划触发它。onReceive 的触发时间由你决定,通常使用 AlarmManager 实现:
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,因此应在子类内部调用,而不是在上面的调度代码中直接调用:
class YourNotificationReceiver : AppsKitSDKLocalNotificationBroadCastReceiver() {
fun intervalMillis(): Long = getTimeIntervalInMilliSeconds()
override fun checkNotifications() { /* ... */ }
}在 Doze 模式或电池优化机制下,
AlarmManager.setRepeating的触发时间并不精确。如果需要在设备空闲时可靠触发,请改为在每次触发后使用setExactAndAllowWhileIdle重新调度,或使用WorkManager的PeriodicWorkRequest(最小间隔为 15 分钟)。AKS 不限定使用哪种方案,请根据应用需求选择。另外请注意,设备重启后闹钟不会保留,除非你自行重新注册(例如在BOOT_COMPLETED接收器中注册)。
9.4 直接显示通知(不使用队列)
如需立即发送通知,而不经过上述队列和接收器流程:
// 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+ 上自行请求运行时权限,否则调用后可能无法发送通知,且不会提示错误。