Apps Kit SDK logoApps Kit SDK
개발자 문서 · Android 연동

9. 로컬 알림 (AppsKitSDKLocalNotificationManager)

AKS는 자체 로컬 알림을 표시할 수 있도록 큐, 알림 빌더, 추상 BroadcastReceiver로 구성된 간단한 로컬 알림 도구를 제공합니다. AKS는 매니페스트에 리시버를 등록하거나 알림을 예약해 주지 않습니다. 두 작업 모두 직접 처리해야 합니다.

9.1 매니페스트

AppsKitSDKLocalNotificationBroadCastReceiver를 상속한 클래스를 만들고(§9.2 참고), 이 클래스를 <receiver>로 선언하여 §2의 <application> 요소 안에 포함되도록 하세요.

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() 안에서 큐에 알림을 추가하면 됩니다.

이 큐 기반 알림 표시 방식은 Android 13 이상에서 POST_NOTIFICATIONS 권한을 자체적으로 확인합니다. 권한이 없으면 로그 한 줄만 남기고 알림 표시를 건너뛰므로, §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로 다음 알람을 예약하거나 WorkManager의 PeriodicWorkRequest(최소 간격 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 이상에서는 런타임 권한을 직접 요청해야 하며, 그렇지 않으면 호출해도 별도 오류 없이 알림이 표시되지 않을 수 있습니다.