Android AlarmManager设置闹钟

官网镇楼:设置重复闹铃时间

闹钟具有以下特征:

  • 它们可让您按设定的时间和/或间隔触发 intent。
  • 您可以将它们与广播接收器结合使用,以启动服务以及执行其他操作。
  • 它们在应用外部运行,因此即使应用未运行,或设备本身处于休眠状态,您也可以使用它们来触发事件或操作。
  • 它们可以帮助您最大限度地降低应用的资源要求。您可以安排定期执行操作,而无需依赖定时器或持续运行后台服务

简单来说,要在设定的时间执行具体的任务,可以用 AlarmManager 来实现。

注:这里说的应用通过 AlarmManager 设置的闹钟 和 系统闹钟应用里设置的闹钟 不一样,不要混淆了。

举个例子,

应用通过 AlarmManager 设置闹钟,到某个时间点获取版本更新信息,简称 A 。

系统闹钟应用里设置的每天早上8点的起床闹钟,简称 B 。

添加 A 时,不会添加到系统闹钟应用里,触发 A 时 ,只会触发应用里的事件(如 Receiver),不会有系统闹钟的声音、震动、UI 弹窗等东西。

触发 B 时,有系统闹钟的声音、震动、UI 弹窗等东西。

初始化

复制代码
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

设置单次闹钟

set

30s 后唤醒设备并触发闹钟

模拟器测试:

  • 设置闹钟后不退出应用,锁屏,到时间可以触发,不会唤醒屏幕;
  • 设置闹钟后退出应用,并清理进程,到时间可以触发;
  • 设置闹钟后退出应用,并清理进程,锁屏,到时间可以触发,不会唤醒屏幕;

使用 PendingIntent 来实现,到时间后会触发 AlarmReceiver.onReceive() ,

复制代码
Intent intent = new Intent(mContext, AlarmReceiver.class);
pendingIntent1 = PendingIntent.getBroadcast(mContext, 0, intent, 0);

alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + 30 * 1000,
            pendingIntent1);

setExact

setExact 和 set 用法是一样的,差别是 setExact 比 set 时间更精确。大白话,setExact 是 30 秒后触发,set 可能 30秒后触发,也可能 35 秒后触发。

30s 后唤醒设备并触发闹钟

复制代码
Intent intent = new Intent(mContext, ExactAlarmReceiver.class);
pendingIntent6 = PendingIntent.getBroadcast(mContext, 6, intent, 0);

alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + 30 * 1000,
            pendingIntent6);

设置重复闹钟

设置重复闹钟用 setInexactRepeating 和 setRepeating 。

  • setInexactRepeating :必须使用指定的时间间隔常量,此方法会同步多个不精确的重复闹钟,并同时触发它们。这样可以减少耗电量。
  • setRepeating :精确闹钟,可以自定义时间间隔。

setInexactRepeating

使用 PendingIntent 和 Calendar 来实现,到时间后会触发 AlarmReceiver.onReceive() ,

在上午 10:10 左右唤醒设备并触发闹钟,

复制代码
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 10);

Intent intent = new Intent(mContext, AlarmReceiver.class);
pendingIntent3 = PendingIntent.getBroadcast(mContext, 0, intent, 0);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent3);

指定的时间间隔有 15 分钟、半小时、一小时、半天、一天,分别对应 :

  • INTERVAL_FIFTEEN_MINUTES
  • INTERVAL_HALF_HOUR
  • INTERVAL_HOUR
  • INTERVAL_HALF_DAY
  • INTERVAL_DAY

setRepeating

使用 PendingIntent 和 Calendar 来实现,到时间后会触发 AlarmReceiver.onReceive() ,

在上午 9:25 准时唤醒设备并触发闹钟,此后每 1 分钟触发一次:

复制代码
Intent intent = new Intent(mContext, AlarmReceiver.class);
pendingIntent4 = PendingIntent.getBroadcast(mContext, 0, intent, 0);

// Set the alarm to start at 9:25 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 25);

// setRepeating() lets you specify a precise custom interval--in this case,
// 1 minutes.
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
            1000 * 60 * 1, pendingIntent4);

取消闹钟

使用 cancel() 方法,传入不想触发的 PendingIntent 即可。

复制代码
if (alarmManager != null) {
   if (null != pendingIntent1) {
        alarmManager.cancel(pendingIntent1);
    }
    if (null != pendingIntent2) {
       alarmManager.cancel(pendingIntent2);
    }
    if (null != pendingIntent3) {
       alarmManager.cancel(pendingIntent3);
    }
  }

获取系统闹钟应用里设置的闹钟

获取系统闹钟应用里设置的闹钟,获取最临近的一个,返回一个 AlarmClockInfo ,

复制代码
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
AlarmManager.AlarmClockInfo info = alarmManager.getNextAlarmClock();

AlarmClockInfo.getTriggerTime() 方法返回的是 UTC 时间,转为日期形式更直观,

复制代码
/**
* 1692453600000 ==> Sat, 2023 08 19 22:00:00 GMT
* */
private String utc2Date(long utcTime){
    Calendar calendar= Calendar.getInstance();
    calendar.setTimeInMillis(utcTime);

    SimpleDateFormat sdfGmt = new SimpleDateFormat("EEE, yyyy MM d HH:mm:ss 'GMT'", Locale.getDefault());//星期三, 2023 08 16 22:00:00 GMT
    sdfGmt.setTimeZone(TimeZone.getDefault());
    return sdfGmt.format(calendar.getTime());
 }
相关推荐
plainGeekDev4 小时前
null 判断 → Kotlin 可空类型
android·java·kotlin
plainGeekDev4 小时前
getter/setter → Kotlin 属性
android·java·kotlin
YXL1111YXL6 小时前
Handler 消息回收与协程异步执行的时序陷阱
android
恋猫de小郭6 小时前
KMP / CMP 鸿蒙版本 Beta 发布,他有什么特别之处?
android·前端·flutter
三少爷的鞋7 小时前
Android 协程并发控制:别动线程池,控制好并发语义就够了
android
weiggle1 天前
第七篇:状态提升与单向数据流——架构设计的核心
android
xingpanvip1 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
goldenrolan1 天前
A公司物料替代测试系统 v1.7:从需求到 exe/apk 的 AI 辅助全链路实践
android·自动化测试·软件测试·python·ai
AC赳赳老秦1 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
骇客之技术1 天前
AutoLua:在安卓上写 Lua 脚本
android·junit·lua