Apps Kit SDK logoApps Kit SDK
Tài liệu · Tích hợp Android

9. Thông báo cục bộ (AppsKitSDKLocalNotificationManager)

AKS cung cấp một bộ công cụ nhỏ cho thông báo cục bộ — gồm hàng đợi, trình tạo thông báo và một lớp BroadcastReceiver trừu tượng — để bạn hiển thị thông báo cục bộ của riêng mình. AKS không đăng ký receiver trong manifest của SDK hay lên lịch thay bạn; bạn cần tự thực hiện cả hai việc này.

9.1 Manifest

Tạo lớp con kế thừa AppsKitSDKLocalNotificationBroadCastReceiver (minh họa tại §9.2) và khai báo lớp con đó dưới dạng <receiver>, gộp vào cùng phần tử <application> ở §2:

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

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

</application>

Nếu ứng dụng nhắm đến Android 13+ (API 33), hãy thêm quyền gửi thông báo được cấp lúc chạy — manifest của AKS không khai báo quyền này nên quyền sẽ không được tự động gộp vào manifest của bạn:

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

POST_NOTIFICATIONS là quyền được cấp lúc chạy, vì vậy bạn vẫn cần yêu cầu người dùng cấp quyền (ví dụ: qua ActivityResultContracts.RequestPermission()) trước khi thông báo có thể thực sự hiển thị.

9.2 Thêm thông báo vào hàng đợi

Tạo lớp con kế thừa AppsKitSDKLocalNotificationBroadCastReceiver và triển khai checkNotifications() — đây là nơi bạn quyết định thông báo đã đến lúc cần hiển thị hay chưa, được gọi mỗi khi receiver được kích hoạt:

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
            )
        )
    }
}

Ngay sau khi checkNotifications() trả về, onReceive tự động gọi AppsKitSDKLocalNotificationManager.showNotification(context) — phương thức này lấy NotificationModel được thêm sớm nhất ra khỏi hàng đợi và hiển thị thông báo đó. Trong luồng này, bạn không cần tự gọi showNotification; chỉ cần thêm thông báo vào hàng đợi bên trong checkNotifications().

Luồng hiển thị qua hàng đợi này tự kiểm tra POST_NOTIFICATIONS trên Android 13+ và bỏ qua mà không báo lỗi (chỉ ghi một dòng log) nếu chưa được cấp quyền, vì vậy hãy nhớ yêu cầu cấp quyền trước theo §9.1.

9.3 Lên lịch

AKS không đăng ký hay kích hoạt receiver này theo bất kỳ lịch nào — bạn quyết định thời điểm onReceive được gọi, thường bằng 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
)

Với intervalMs, bạn có thể đặt cố định khoảng thời gian lặp hoặc sử dụng giá trị cấu hình từ xa trên cổng quản lý AKS (HOURS_TO_MAKE_NOTIFICATION, mặc định là 2 giờ nếu chưa thiết lập). Giá trị này được cung cấp qua getTimeIntervalInMilliSeconds() trong lớp receiver cơ sở, nhưng phương thức có phạm vi truy cập protected, nên hãy gọi từ bên trong lớp con thay vì từ đoạn mã gọi ở trên:

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

AlarmManager.setRepeating không đảm bảo thời điểm kích hoạt chính xác khi Doze hoặc các cơ chế tối ưu hóa pin hoạt động — nếu cần kích hoạt ổn định khi thiết bị ở trạng thái nhàn rỗi, hãy lên lịch lại bằng setExactAndAllowWhileIdle sau mỗi lần kích hoạt, hoặc chuyển sang PeriodicWorkRequest của WorkManager (khoảng thời gian lặp tối thiểu là 15 phút). AKS không bắt buộc dùng phương án nào; hãy chọn phương án phù hợp với ứng dụng của bạn. Cũng lưu ý rằng lịch hẹn không được giữ lại sau khi thiết bị khởi động lại, trừ khi bạn tự đăng ký lại (ví dụ: từ receiver nhận BOOT_COMPLETED).

9.4 Hiển thị thông báo trực tiếp (không qua hàng đợi)

Để hiển thị thông báo ngay lập tức mà không đi qua luồng hàng đợi/receiver ở trên:

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
)

Cả hai phiên bản nạp chồng đều tự tạo kênh thông báo nếu kênh chưa tồn tại. Khác với luồng qua hàng đợi ở §9.2, cả hai đều không tự kiểm tra POST_NOTIFICATIONS — bạn cần tự yêu cầu cấp quyền lúc chạy trên Android 13+, nếu không, lời gọi có thể không hiển thị thông báo mà không báo lỗi.