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());
 }
相关推荐
闲暇部落33 分钟前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX3 小时前
Android 分区相关介绍
android
大白要努力!4 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee4 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood4 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-7 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen9 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年16 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿19 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神20 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri