news 2026/6/18 13:37:27

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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. 第二次设置的闹钟会直接覆盖第一次设置的闹钟,最终系统只会保留并触发第二次设置的闹钟

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/18 13:37:16

Claude Code + Opus 4.6:从自动补全到规格驱动开发的范式升级

1. 这不是“装个插件”&#xff0c;而是一次开发范式的迁移&#xff1a;Claude Code Opus 4.6 的真实定位你点开这篇文章&#xff0c;大概率不是为了学一个新工具的安装步骤——毕竟网上搜“Claude Code 安装”能出几百篇教程。真正让你停下来的&#xff0c;是标题里那个带着温…

作者头像 李华
网站建设 2026/6/18 13:34:11

5分钟告别网盘限速:九大平台直链解析工具完全指南

5分钟告别网盘限速&#xff1a;九大平台直链解析工具完全指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘…

作者头像 李华
网站建设 2026/6/18 13:32:31

网盘直链下载助手终极指南:一键获取九大平台真实下载地址

网盘直链下载助手终极指南&#xff1a;一键获取九大平台真实下载地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…

作者头像 李华
网站建设 2026/6/18 13:30:18

托管式GEO优化效果更稳定吗

企业做GEO有两种主流模式&#xff1a;自己组建或培训团队来运营&#xff08;自助模式&#xff09;&#xff0c;或者委托专业服务商全包运营&#xff08;托管模式&#xff09;。托管模式是否效果更稳定&#xff1f;从实战经验来看&#xff0c;答案是肯定的——但需要理解“稳定”…

作者头像 李华
网站建设 2026/6/18 13:28:01

VALMET ND9103HXT/I02 定位器工业落地应用指南

在化工与能源生产一线&#xff0c;阀门控制系统的稳定性往往直接决定了整条产线的安危与效率。很多工程师都遇到过这样的棘手场景&#xff1a;在高温高压、强振动或复杂电磁干扰的严苛工况下&#xff0c;传统的气动执行机构容易出现响应滞后、定位漂移甚至误动作。这不仅导致工…

作者头像 李华
网站建设 2026/6/18 13:24:00

企业级实验室信息管理:SENAITE LIMS的架构设计与生产部署方案

企业级实验室信息管理&#xff1a;SENAITE LIMS的架构设计与生产部署方案 【免费下载链接】senaite.lims SENAITE Meta Package 项目地址: https://gitcode.com/gh_mirrors/se/senaite.lims 在数字化实验室转型的关键时期&#xff0c;技术决策者面临的核心挑战是如何在保…

作者头像 李华