当前位置: 首页 > news >正文

Android AlarmManager - AlarmManager 初识、精确闹钟权限、闹钟覆盖

一、AlarmManager 初识

1、基本介绍
  1. AlarmManager 是 Android 系统提供的全局定时服务,用于在指定时间触发任务

  2. 从 Android 4.4(API 19)开始,系统默认将闹钟调整为不精确的,以批量处理任务、减少设备唤醒,从而显著省电

  3. 只有在特殊需求时,才应使用精确闹钟,例如,闹钟应用

  • 设置闹钟前,需要先确定时间基准,主要如下两种
类型说明
ELAPSED_REALTIME系统启动后经过的时间,适用于相对时间间隔的场景
RTC真实世界时间,适用于特定时刻触发的场景
  • XXX_WAKEUP类型的闹钟(例如,RTC_WAKEUP)能在设备休眠时唤醒 CPU,非唤醒版本的闹钟要等到设备下次自然唤醒才能执行
2、演示
(1)Receiver
  • MyAlarmReceiver.java
publicclassMyAlarmReceiverextendsBroadcastReceiver{publicstaticfinalStringTAG=MyAlarmReceiver.class.getSimpleName();@OverridepublicvoidonReceive(Contextcontext,Intentintent){Log.i(TAG,"触发了!!!");}}
  • AndroidManifest.xml
<receiverandroid:name=".receiver.MyAlarmReceiver"android:exported="false"/>
(2)Activity
ButtonbtnSetAlarm=findViewById(R.id.btn_set_alarm);btnSetAlarm.setOnClickListener(v->{AlarmManageralarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);Intentintent=newIntent(this,MyAlarmReceiver.class);PendingIntentpendingIntent=PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_IMMUTABLE);alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+5*1000,pendingIntent);});

二、精确闹钟权限

1、基本介绍
  1. 从 Android 12 开始,使用精确闹钟必须声明权限,否则报错

  2. 从 Android 12 开始,调用精确闹钟前,务必使用 canScheduleExactAlarms 方法检查权限

2、演示
  1. 执行如下代码,Android 10 正常执行,Android 13 报错,错误信息如下
ButtonbtnSetAlarm=findViewById(R.id.btn_set_alarm);btnSetAlarm.setOnClickListener(v->{AlarmManageralarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);Intentintent=newIntent(this,MyAlarmReceiver.class);PendingIntentpendingIntent=PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_IMMUTABLE);alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+5*1000,pendingIntent);});
# 输出结果 FATAL EXCEPTION: main Process: com.my.alarmmanager, PID: 4754 java.lang.SecurityException: Caller com.my.alarmmanager needs to hold android.permission.SCHEDULE_EXACT_ALARM or android.permission.USE_EXACT_ALARM to set exact alarms.
  1. Android 13 执行如下代码,检查权限
AlarmManageralarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){Log.i(TAG,"Android 12 及以上");booleanresult=alarmManager.canScheduleExactAlarms();Log.i(TAG,"result: "+result);}else{Log.i(TAG,"Android 12 以下");}
# 输出结果 Android 12 及以上 result: false
3、请求权限
  1. 在 AndroidManifest.xml 文件中声明权限
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
  1. 检查权限与引导授权
publicclassMainActivityextendsAppCompatActivity{publicstaticfinalStringTAG=MainActivity.class.getSimpleName();privateAlarmManageralarmManager;@SuppressWarnings("all")@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main),(v,insets)->{InsetssystemBars=insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom);returninsets;});alarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);if(checkExactAlarmPermission()){next();}else{ActivityResultLauncher<Intent>intentActivityResultLauncher=registerForActivityResult(newActivityResultContracts.StartActivityForResult(),o->{booleanresult=alarmManager.canScheduleExactAlarms();if(result){next();}else{Toast.makeText(this,"未获取到相关权限,无法使用本功能",Toast.LENGTH_SHORT).show();finish();}});Intentintent=newIntent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);intentActivityResultLauncher.launch(intent);}}privatebooleancheckExactAlarmPermission(){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S){Log.i(TAG,"Android 12 及以上");booleanresult=alarmManager.canScheduleExactAlarms();Log.i(TAG,"result: "+result);returnresult;}else{Log.i(TAG,"Android 12 以下");returntrue;}}privatevoidnext(){ButtonbtnSetAlarm=findViewById(R.id.btn_set_alarm);btnSetAlarm.setOnClickListener(v->{AlarmManageralarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);Intentintent=newIntent(this,MyAlarmReceiver.class);PendingIntentpendingIntent=PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_IMMUTABLE);alarmManager.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+5*1000,pendingIntent);});}}

三、闹钟覆盖

1、演示
(1)Receiver
  • TestAlarmReceiver.java
publicclassTestAlarmReceiverextendsBroadcastReceiver{publicstaticfinalStringTAG=TestAlarmReceiver.class.getSimpleName();@SuppressWarnings("all")@OverridepublicvoidonReceive(Contextcontext,Intentintent){LocalDateTimedateTime=LocalDateTime.now();DateTimeFormatterformatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");Stringstr=dateTime.format(formatter);Log.i(TAG,"onReceive: "+str);Log.i(TAG,"触发了!!!");}}
  • AndroidManifest.xml
<receiverandroid:name=".receiver.TestAlarmReceiver"android:exported="false"/>
(2)Activity
ButtonbtnSetAlarm=findViewById(R.id.btn_set_alarm);btnSetAlarm.setOnClickListener(v->{LocalDateTimedateTime=LocalDateTime.now();DateTimeFormatterformatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");Stringstr=dateTime.format(formatter);Log.i(TAG,"btnSetAlarm click: "+str);AlarmManageralarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);Intentintent=newIntent(this,TestAlarmReceiver.class);PendingIntentpendingIntent=PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_IMMUTABLE);alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+5000,pendingIntent);});
(3)Test
  • 连续两次按钮,输出如下内容
btnSetAlarm click: 2026-06-15 10:01:53 btnSetAlarm click: 2026-06-15 10:01:56 onReceive: 2026-06-15 10:02:01 触发了!!!
2、基本介绍
  1. AlarmManager 判断两个闹钟是否为同一个任务,是通过 PendingIntent 来进行匹配的

  2. 两次执行时,requestCode 都是 0,Intent 也都是指向TestAlarmReceiver.class的,因此生成的 PendingIntent 都是相同的

  3. 第二次设置的闹钟会直接覆盖第一次设置的闹钟,最终系统只会保留并触发第二次设置的闹钟

http://www.jsqmd.com/news/1036160/

相关文章:

  • 011、反激变压器的匝比计算
  • 2026年河南汝瓷礼品定制哪家好?源头工厂深度横评与企业采购避坑指南 - 优质企业观察收录
  • 儒意电影发布超级娱乐空间2.0战略,以超级场景与超级IP双轮驱动,AI赋能文娱全产业链
  • 【课程设计/毕业设计】基于 Python+Django 的高校请假信息统计可视化平台的设计与实现 基于 Python+Django 的大学生请假台账可视化管理系统【附源码、数据库、万字文档】
  • Grok 4 Heavy深度解析:多智能体协同如何重构AI工程实践
  • 3个颠覆性功能:重新定义你的音频创作体验
  • StarCore SC100链接器深度解析:从符号解析到缓存优化的嵌入式DSP开发实践
  • 如何解决网盘下载限速问题?8大平台直链下载助手终极指南
  • MQX RTOS任务管理、调度与内存同步机制深度解析
  • 我的AI Agent7天零基础入门实战计划
  • VALMET ND9106HX8T 阀门定位器实战应用与故障排查指南
  • 6月淮北黄金回收市场实测观察:卖金套路多,市民如何避坑? - 微城市网络
  • 终极宝可梦合法性解决方案:PKHeX自动合规插件完全指南
  • 无锡视频拍摄公司排行:基于服务与案例的客观盘点 - 起跑123
  • 制袋机行业标杆:正威制袋机技术领先的绿色包装选择 - 速递信息
  • 强烈推荐:智能电视最全ADB软件合集!可以给电视或者盒子安装软件的工具!安卓端电脑端都有
  • 深入解析I2C总线:从基础协议到多控制器通信与实战调试
  • 2026 上海小型冷库安装公司电话,保鲜冷库安装服务咨询指南 - 品牌2026
  • 2026年6月重磅速报:高端腕表养护必读——北京亨得利手表维修收费价格表深度拆解 - 亨得利官方售后
  • CIO 的第一视角:旧式企业 IM 正在拖慢业务决策的三重死结
  • Python爬虫接入站大爷代理IP完整教程(附可运行代码)|两种授权模式全覆盖,自带反爬防封禁策略
  • 解决“找不到求解器”错误:环境变量PATH配置与跨平台调试指南
  • 5分钟打造你的Obsidian个人知识管理中心:告别笔记混乱,开启高效学习新纪元
  • 【多智能体控制】基于预定时间非干扰形成控制开放多智能体系统Matlab仿真
  • 2026年全国家庭教育优质课程服务机构排行及适配指南 - 互联网科技品牌测评
  • 2026年,热门AI搜索优化企业名声几何?
  • 2026年上海防水补漏服务商全景评测:从AI漏点检测到15年质保的完整选型指南 - 优质企业观察收录
  • ALMA望远镜揭示原行星盘与行星形成的奥秘
  • 武汉奢侈品回收门店横向测评|2026 闲置包包手表黄金变现避坑完整干货 - 奢品屋武汉奢侈品回收
  • 学生党必看!平价好用粉饼大揭秘 - 品牌测评鉴赏家