当前位置: 首页 > 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.gsyq.cn/news/1548060.html

相关文章:

  • 3个颠覆性功能:重新定义你的音频创作体验
  • VALMET ND9106HX8T 阀门定位器实战应用与故障排查指南
  • 终极宝可梦合法性解决方案:PKHeX自动合规插件完全指南
  • 无锡视频拍摄公司排行:基于服务与案例的客观盘点 - 起跑123
  • 【多智能体控制】基于预定时间非干扰形成控制开放多智能体系统Matlab仿真
  • 2026年上海防水补漏服务商全景评测:从AI漏点检测到15年质保的完整选型指南 - 优质企业观察收录
  • 胶东机场至诸城拼车发车机制及服务细节全解析 - 起跑123
  • FrogMouth:一款用户友好型MarkDown阅读器
  • 换发型不伤发!武汉三星速美假发超市线下探店实测 - 行业深度观察C
  • 2026年供应商交期反复延迟,采购人员学习众智商学院SCMP前怎么复盘交付管理问题? - 众智商学院职业教育
  • 语言贬低式家庭教育对儿童人格发展的负面影响及正向教养路径探析
  • 新疆旅游季节和路线选择参考 - 盛世西域旅行
  • 2026 京东 e 卡回收实操教程,闲置礼品卡安全变现指南 - 京卡收卡券回收
  • OCAT终极指南:3步搞定OpenCore黑苹果配置,告别复杂XML编辑
  • AI生活化应用设计:从技术能力到温情体验的产品化思考
  • 2026年上海防水补漏服务商选型指南:从漏点诊断到15年质保的完整避坑手册 - 优质企业观察收录
  • 为什么选数控弯箍机不能只看榜单附6维选型法 + 源头工厂实测 - 资讯快报
  • 全球Token降价潮启动:AI大模型API价格雪崩,最高降幅达99%
  • 丽水GEO城市合伙人选型推荐哪家靠谱:源头厂商、合伙人权益与区域保护怎么选? - 小随科技
  • LX Music桌面版:一站式跨平台音乐聚合播放器终极指南
  • 2026瑞安黄金回收市场调查:卖金套路多,市民直呼“水太深” - 微城市网络
  • 计算机毕业设计之学生信息管理系统
  • 应急响应实战:从挖矿木马入侵到系统加固的完整处置流程
  • 上海黄金回收防坑指南|五区正规门店实测与交易全流程拆解 - 昌福黄金回收
  • AI应用开发面试题精讲(四):系统架构与生产落地高频15问
  • 5分钟免费激活Windows和Office:告别激活弹窗的完整指南
  • WPS虚拟打印机消失?系统级排查与修复全指南
  • 【共创季稿事节】HarmonyOS7 互动卡片开发实践:写一个能加载页面的最小 LiveForm Ability
  • 美妆博主分享:2026年适合新手的6款粉饼推荐 - 品牌测评鉴赏家
  • M2.7开源模型深度解析:Agentic-first架构与非商业许可下的工程实践