Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách đặt lịch thông báo cục bộ trong Android (Local Notification Scheduling)

Giới thiệu

Bài này trùng lặp với bài 1003061556 (cùng code AlarmManager + BroadcastReceiver). Dưới đây là bản tóm tắt so sánh các phương pháp đặt lịch thông báo cục bộ hiện đại.

So sánh 3 phương pháp chính

Tiêu chíAlarmManager + BroadcastReceiverWorkManagerHandler/Timer (trong Service)
Độ chính xác thời gianCao (giây) - setExactAndAllowWhileIdleThấp (cửa sổ 15p+)Cao (nếu Service sống)
Sống sau rebootCần BOOT_COMPLETED receiverTự độngKhông (Service bị kill)
Tiết kiệm pinThấp (wake lock)Cao (JobScheduler)Thấp
Phức độ codeTrung bìnhThấpThấp
Phù hợp choBáo thức, nhắc lịch chính xácSync dữ liệu, backup, logForeground service đang chạy

Khuyến nghị chọn phương pháp

  • Báo thức, nhắc uống thuốc, lịch hẹn chính xác: AlarmManager + setExactAndAllowWhileIdle() + BroadcastReceiver.
  • Đồng bộ dữ liệu định kỳ, upload log, backup: WorkManager (PeriodicWorkRequest).
  • Thông báo trong khi app đang chạy foreground: Handler.postDelayed() hoặc Coroutine delay.

Ví dụ WorkManager (Periodic)

// 1. Worker
public class DailyReminderWorker extends CoroutineWorker {
    public DailyReminderWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
        showNotification("Nhắc nhở hàng ngày", "Đến giờ uống nước!");
        return Result.success();
    }
    // ... showNotification như cũ
}

// 2. Enqueue (chạy mỗi ngày vào 8h sáng)
Constraints constraints = new Constraints.Builder()
        .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
        .build();

PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(DailyReminderWorker.class, 24, TimeUnit.HOURS)
        .setInitialDelay(calculateDelayUntil8AM(), TimeUnit.MILLISECONDS)
        .setConstraints(constraints)
        .build();

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
        "daily_water_reminder", ExistingPeriodicWorkPolicy.KEEP, request);

Ví dụ AlarmManager cho báo thức chính xác

// Đặt báo thức 7:00 sáng mai
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
    calendar.add(Calendar.DAY_OF_YEAR, 1);
}

Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 
        PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

Kết luận

Đối với "Schedule local notification", hãy chọn:

  • AlarmManager nếu cần độ chính xác cao (báo thức, reminder có giờ cố định).
  • WorkManager nếu chỉ cần "khoảng lúc đó" và muốn tiết kiệm pin, bền vững qua reboot.