Giới thiệu
Bài này trùng lặp hoàn toàn với bài 1003061556 và 1003061557 (cùng source code AlarmManager + BroadcastReceiver). Xem chi tiết tại các bài đó.
Tóm tắt nhanh quy trình
- Tạo
BroadcastReceiver(MyNotificationPublisher) xử lý hiển thị notification. - Trong Activity, tạo
Notificationobject, gói vào Intent. - Tạo
PendingIntent.getBroadcast()với FLAG_UPDATE_CURRENT. - Dùng
AlarmManager.setExactAndAllowWhileIdle()đặt hẹn giờ. - Khai báo receiver trong Manifest, xin quyền SCHEDULE_EXACT_ALARM (API 31+).
Code mẫu rút gọn (chỉ phần khác)
PendingIntent flags quan trọng
// FLAG_UPDATE_CURRENT: Cập nhật extra data nếu PendingIntent đã tồn tại (cùng requestCode)
// FLAG_IMMUTABLE: Bắt buộc API 31+, an toàn hơn
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, requestCode, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
Xử lý reboot (Boot Completed)
// Manifest
<receiver android:name=".BootReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
// BootReceiver.java
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
// Reschedule all alarms ở đây
rescheduleAlarms(context);
}
}
}
Checklist triển khai production
- [ ] Tạo Notification Channel riêng cho scheduled notifications
- [ ] Dùng requestCode khác nhau cho mỗi loại thông báo
- [ ] FLAG_UPDATE_CURRENT trên PendingIntent
- [ ] setExactAndAllowWhileIdle cho độ chính xác
- [ ] Xử lý BOOT_COMPLETED để đặt lại alarm sau reboot
- [ ] Kiểm tra canScheduleExactAlarms() API 31+
- [ ] Xin quyền POST_NOTIFICATIONS runtime API 33+
- [ ] Test Doze mode (adb shell dumpsys deviceidle force-idle)