setExactAndAllowWhileIdle() for alarmmanager 工作不正常

2022-09-04 19:31:07

我正在开发一个应用程序,它需要在用户设置的确切时间执行特定操作。为此,我正在使用方法,因为本文档说具有android 6.0或更高版本的Android设备具有doze模式概念,其中如果设备保持空闲状态一段时间,那么它将进入doze模式并且doze模式限制警报。如果我想在设备进入打瞌睡模式时触发警报,那么我有文档所说的方法。本文档还包含用于测试目的的将设备进入低电耗模式的手动方法。因此,我正在使用这种方式进行测试,但是当设备进入打瞌睡模式时,我的警报不会触发,当我通过终端命令停止打瞌睡模式时,我过去的警报将立即触发。setExactAndAllowWhileIdle()setExactAndAllowWhileIdle()

所以,我的问题是这种方法在低潮模式下不起作用,但它应该必须像文档中所说的那样工作。我知道这种方法的局限性,我每9分钟只能发出一个警报,我遵循这个规则。所以,我不明白问题出在哪里。setExactAndAllowWhileIdle()

我的代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC, d.getTime(), pendingIntent);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    alarmManager.setExact(AlarmManager.RTC, d.getTime(), pendingIntent);
else
    alarmManager.set(AlarmManager.RTC, d.getTime(), pendingIntent);

是方法问题还是我以错误的方式做了??


答案 1

我已经找到了我的问题的解决方案,所以,我在这里发布我自己的答案,这对我有用。

使用setAlarmClock()方法解决了我的问题。如果您使用 setAlarmClock() 方法设置闹钟,则不允许系统在闹钟时间的 1 小时之前进入打瞌睡模式。我通过手动强制设备在设置闹钟后进入打瞌睡模式对此进行了测试。让我解释一下完整的场景。

  1. 首先,我从当前时间开始5分钟后设置警报,然后尝试使用以下命令手动将设备置于打瞌睡模式。

adb shell dumpsys deviceidle force-idle

它显示

无法进入打瞌睡模式

  1. 之后,我从当前时间开始1小时1分钟后设置闹钟,然后我尝试将设备置于打瞌睡模式,它成功进入打瞌睡模式。然后我在我的设备上什么也没做,即使它处于打瞌睡模式,它也准时发出警报。

因此,我得出结论,如果当前时间和闹钟时间之间存在少量时间戳,setAlarmClock()方法会阻止您的设备进入打瞌睡模式。否则,如果您的设备已经处于打瞌睡模式,那么它将在闹钟发出一段时间之前从低电打模式退出,因此,您的闹钟工作正常。

更新代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
    alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(d.getTime(),pendingIntent),pendingIntent);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    alarmManager.setExact(AlarmManager.RTC, d.getTime(), pendingIntent);
else
    alarmManager.set(AlarmManager.RTC, d.getTime(), pendingIntent);

答案 2

您可以通过忽略电池优化将应用程序从低电耗模式列入白名单。

添加权限

<uses-permission 
android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>

请求将您的应用列入白名单

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Intent intent = new Intent();
            String packageName = getPackageName();
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + packageName));
                startActivity(intent);
            }
        }

注意:setAndAllowWhileIdle() 和 setExactAndAllowWhileIdle() 都不能为每个应用每 15 分钟发出一次以上的警报。


推荐