Android 14 : 精确时钟进一步被限制(SCHEDULE_EXACT_ALARM)

2,300 阅读3分钟

精确警报——能够使设备退出睡眠模式,睡眠模式作为 Android 的核心节电限制之一,可防止大多数后台活动在重复出现的“运行窗口”之外发生。

因此,如果太多应用程序在不同时间安排了准确的警报,那么设备就不能保持长时间睡眠,从而增大电量损耗。

  • 版本权限获取方式
    Android 12SCHEDULE_EXACT_ALARMAPP安装时自动授权
    Android 13SCHEDULE_EXACT_ALARMtargetSDK <33 APP安装时自动授权targetSDK 33默认关闭,运行时请求
    Android 14SCHEDULE_EXACT_ALARMUSE_EXACT_ALARM默认关闭,引导用户开启安装应用时授权(需接受谷歌审核)

Android14 以前已经授权的应用OTA到Android14时继续被授权,但是如果用户通过备份还原操作将应用数据传输到运行Android 14的设备上,权限会被拒绝。

  • Android 14 中处于以下条件的APP将收到此改动影响。

    1. targetSdk为 33 以及更高版本。
    2. SCHEDULE_EXACT_ALARM在Manifest中声明权限。
    3. 不是日历或闹钟应用程序
    4. 不属于豁免授权前 情形。豁免:1. 使用平台证书签名的APP
    1. privilege应用程序

      1. Android 8.1 及更低版本 - /system
      2. Android 9 及更高版本 - /system, /product, /vendor
    2. 电池优化策略许可名单上的应用程序(如果应用程序符合要求,可以使用 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)
    }