在 Android 中,AlarmManager 是一个系统服务,用于在特定时间或周期性地触发操作(如启动服务、发送广播等)。即使应用在后台或被杀死,也可以触发设定的事件,因此广泛用于定时任务、定期通知等场景。


🔔 10.5 AlarmManager(闹钟服务)

📘 基本介绍:

  • 类名:android.app.AlarmManager
  • 功能:设置一次性或周期性闹钟(定时器)。
  • 适用场景:
    • 定期更新数据(如天气、新闻)
    • 定期推送通知
    • 延迟任务执行
    • 定时启动后台服务等

✅ 常用方法:

方法描述
set()设置一次性闹钟
setRepeating()设置周期性闹钟(Android API 19 后已不精确)
setExact()设置精确的一次性闹钟(API 19+)
setWindow()设置在某个时间窗口内触发
cancel()取消一个已设定的闹钟

🔧 使用步骤:

1. 获取 AlarmManager 实例:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

2. 创建一个 PendingIntent:

Intent intent = new Intent(this, AlarmReceiver.class); // 目标广播接收器
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

3. 设置闹钟:

long triggerTime = System.currentTimeMillis() + 10 * 1000; // 10秒后触发

alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);

🧨 注意事项:

  • RTC_WAKEUP:表示以“真实世界时间”为基准,并唤醒设备。
  • ELAPSED_REALTIME:表示以“设备启动时间”为基准(不会因系统时间变化而变化)。
  • Android 6.0+ 设备进入 Doze 模式后,AlarmManager 行为会受到限制。推荐使用 WorkManager 或 JobScheduler 来替代周期性任务。

📦 示例:一次性闹钟 + 广播接收器

MainActivity.java

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
long triggerAtMillis = System.currentTimeMillis() + 5000; // 5秒后
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "闹钟响啦!", Toast.LENGTH_SHORT).show();
        // 可在此启动服务、通知等
    }
}

AndroidManifest.xml 注册广播

<receiver android:name=".AlarmReceiver" />

🧠 拓展知识:

  • 精准 vs 非精准闹钟
    • setExact() 精准触发,但不能重复(可结合 setAndAllowWhileIdle())。
    • setRepeating() 可能不准,尤其在 Doze 模式中。
  • 在 Doze 模式下工作的方法(API 23+)alarmManager.setAndAllowWhileIdle( AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent );

✅ 小结:

类型方法是否唤醒是否精确支持 Doze
一次性set()❌ 取决于类型
精确setExact()
精确 + DozesetAndAllowWhileIdle()
重复setRepeating()❌(API 19+)

如果你希望实现一个完整的定时推送、服务启动、闹钟 App,或者需要兼容不同 Android 版本,我可以帮你进一步封装。需要完整 Demo 的话可以告诉我。