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());
 }
相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone2 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen2 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone2 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui