Apps Kit SDK logoApps Kit SDK
Tài liệu · AppsKitSDK (AKS) — Hướng dẫn tích hợp Android

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

AKS cung cấp một bộ công cụ gọn 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 giúp 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>, hợp nhất 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 thông báo cần được cấp khi chạy — manifest của AKS không khai báo quyền này, nên quyền sẽ không tự động được hợp nhất vào manifest của ứng dụng:

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

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

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à điểm mở rộng để bạn quyết định đã đến lúc hiển thị thông báo 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à âm thầm bỏ qua (có ghi một dòng log) nếu quyền chưa được cấp, vì vậy hãy đảm bảo bạn đã 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 khi nào onReceive được gọi, thường là 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 chu kỳ riêng hoặc sử dụng giá trị trong cấu hình từ xa trên cổng thông tin AKS (HOURS_TO_MAKE_NOTIFICATION, mặc định là 2 giờ nếu chưa được thiết lập). Bạn có thể lấy giá trị này qua getTimeIntervalInMilliSeconds() trên lớp receiver cơ sở, nhưng phương thức này có phạm vi truy cập protected, nên hãy gọi từ bên trong lớp con thay vì tại vị trí 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 chịu ảnh hưởng của Doze/cơ chế tối ưu hóa pin — nếu cần kích hoạt đáng tin cậy 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 tối thiểu là 15 phút). AKS không bắt buộc dùng cách nào; hãy chọn cách phù hợp với ứng dụng của bạn. Cũng lưu ý rằng lịch báo thức 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 khi 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.