Apps Kit SDK logoApps Kit SDK
개발자 문서 · AppsKitSDK (AKS) — 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 이상에서는 런타임 권한을 직접 요청해야 하며, 그렇지 않으면 별도의 오류 없이 알림이 표시되지 않을 수 있습니다.