精确警报——能够使设备退出睡眠模式,睡眠模式作为 Android 的核心节电限制之一,可防止大多数后台活动在重复出现的“运行窗口”之外发生。
因此,如果太多应用程序在不同时间安排了准确的警报,那么设备就不能保持长时间睡眠,从而增大电量损耗。
-
版本 权限 获取方式 Android 12 SCHEDULE_EXACT_ALARM APP安装时自动授权 Android 13 SCHEDULE_EXACT_ALARM targetSDK <33 APP安装时自动授权targetSDK 33默认关闭,运行时请求 Android 14 SCHEDULE_EXACT_ALARMUSE_EXACT_ALARM 默认关闭,引导用户开启安装应用时授权(需接受谷歌审核)
Android14 以前已经授权的应用OTA到Android14时继续被授权,但是如果用户通过备份还原操作将应用数据传输到运行Android 14的设备上,权限会被拒绝。
-
Android 14 中处于以下条件的APP将收到此改动影响。
1. targetSdk为 33 以及更高版本。 2. SCHEDULE_EXACT_ALARM在Manifest中声明权限。3. 不是日历或闹钟应用程序 4. 不属于豁免或授权前 情形。 豁免:1. 使用平台证书签名的APP -
privilege应用程序
- Android 8.1 及更低版本 -
/system - Android 9 及更高版本 -
/system, /product, /vendor
- Android 8.1 及更低版本 -
-
电池优化策略许可名单上的应用程序(如果应用程序符合要求,可以使用 intent 操作请求
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,谷歌不会轻易授权) |
-
如果时钟或者日历类应用想要改变默认状态,继续使用精准闹钟,有以下几种方式:
- 第一个是设置
USE_EXACT_ALARM权限,安装应用时授权(在Manifest设置权限,上线谷歌商店需要接收Google审核(不上线谷歌商店无影响),应用不运行时也可精确报警,无特殊的理由谷歌不会通过这个权限): -
<manifest ...> //第一个方式 //请求USE_EXACT_ALARM普通权限需要接收Google审核 <uses-permission android:name="android.permission.USE_EXACT_ALARM" /> </manifest>
- 第二个就是引导用户去开启权限
-
<manifest ...> //第二个方式 //请求SCHEDULE_EXACT_ALARM,需要引导用户去打开权限 <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> </manifest> -
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { when { // 使用之前,应该先调用canScheduleExactAlarms()方法来判断权限 alarmManager.canScheduleExactAlarms() -> { Toast.makeText(this, "可以设置精确闹钟", Toast.LENGTH_SHORT).show() } else -> { Toast.makeText(this, "不可以设置精确闹钟", Toast.LENGTH_SHORT).show() // 如果没有的话,可以发起ACTION_REQUEST_SCHEDULE_EXACT_ALARM这个Intent来跳转到设置界面, // 提醒用户手动打开授权。 startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM)) } } }
值得注意的是SCHEDULE_EXACT_ALARM权限并不如USE_EXACT_ALARM权限,即使程序没有运行,也可以执行精确时钟任务。
所以即使我们引导用户去授予我们SCHEDULE_EXACT_ALARM权限,假如在改时间段应用没有存活或者手机处于睡眠状态,那么进准时钟的功能也不会被执行。这个跟WorkManger有着相同的触发机制。
除了用户刻意杀死APP,就是APP获取电池优化策略名单,从而可以在睡眠模式下不保持APP存活。下面是谷歌代码。
-
// 1。 首先声明权限 <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> -
// 2. 判断是否有此权限,没有的情况下获取用户同意 val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) val powerManager = getSystemService(POWER_SERVICE) as PowerManager if (powerManager.isIgnoringBatteryOptimizations(packageName)) { Toast.makeText(this, "此应用已存在电池优化白名单", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, "请求用户同意app加入电池优化白名单", Toast.LENGTH_SHORT).show() intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS intent.data = Uri.parse("package:$packageName") startActivity(intent) }