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 tự lên lịch cho bạn; bạn cần tự thực hiện cả hai việc này.
9.1 Manifest
Tạo lớp kế thừa AppsKitSDKLocalNotificationBroadCastReceiver (minh họa tại §9.2) và khai báo lớp đó dưới dạng <receiver>, gộp vào cùng phần tử <application> ở §2:
<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 khai báo thêm quyền thông báo cần xin 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:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />POST_NOTIFICATIONS là quyền cần xin lúc chạy, vì vậy 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ể hiển thị thông báo.
9.2 Đưa thông báo vào hàng đợi
Tạo lớp kế thừa AppsKitSDKLocalNotificationBroadCastReceiver và triển khai checkNotifications() — đây là nơi 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:
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 đưa 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 quyền
POST_NOTIFICATIONStrên Android 13+ và bỏ qua việc hiển thị 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 đả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 thời điểm onReceive được gọi, thường bằng 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
)Với intervalMs, bạn có thể đặt cứng chu kỳ mong muốn hoặc dùng giá trị trong 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 được đặt). 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 có phạm vi truy cập protected, nên hãy gọi từ bên trong lớp kế thừa thay vì tại vị trí gọi ở trên:
class YourNotificationReceiver : AppsKitSDKLocalNotificationBroadCastReceiver() {
fun intervalMillis(): Long = getTimeIntervalInMilliSeconds()
override fun checkNotifications() { /* ... */ }
}
AlarmManager.setRepeatingkhô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 đá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ằngsetExactAndAllowWhileIdlesau mỗi lần kích hoạt, hoặc chuyển sangPeriodicWorkRequestcủaWorkManager(chu kỳ tối thiểu 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 các 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ừ một receiver nhậnBOOT_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:
// 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ị được thông báo mà không báo lỗi.