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の付与状況を内部で確認し、未付与の場合はログを 1 行出力するだけで通知の表示をスキップします。§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 以降では、アプリ側でランタイム権限をリクエストしてください。そうしないと、呼び出してもエラーなどが示されず、通知が表示されない場合があります。