setExactAndAllowWhileIdle 在打瞌睡模式下使用唤醒锁
setExactAndAllowWhileIdle with Wakelock in Doze mode
似乎有一些与主题相关的问题,但我还没有找到明确的yes/no答案。
我有一个调用 setExactAndAllowWhileIdle
来启动 BroadcastService 的前台服务。下面是广播接收器中的代码。
public class StepCountUpdaterAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myExampleApp::UpdateSteps");
wakeLock.acquire(3);
StepCounterHandler handler = StepCounterHandler.getInstance();
new TaskRunner().executeAsync(
new SetStepsForDay(SaveSharedPreference.getMemberId(context),
handler.getCumulativeSteps()),result -> {
handler.setAlarm(context);
if(isTimeToReset())
handler.resetStepsCounter();
});
wakeLock.release();
}
在 setExactAndAllowWhileIdle
documentation 中指出:
When the alarm is dispatched, the app will also be added to the
system's temporary power exemption list for approximately 10 seconds
to allow that application to acquire further wake locks in which to
complete its work.
但在打瞌睡模式下 documentation 它指出这是一个限制:
The system ignores wake locks.
这是否意味着 setExactAndAllowWhileIdle
在 Doze 模式下发出的警报提供的 10 秒 window 中获取 3 分钟的部分唤醒锁定实际上是无用的,还是可以正常工作?
在我的例子中,广播接收器将通过该异步任务将数据发送到我的远程服务器,然后它会再次设置警报并重置我的步数计数器。这行得通吗?如果行不通,在打瞌睡模式下发送网络请求并执行后续代码的替代方案是什么?
编辑:通过调试我的应用程序进行的测试表明,当强制设备进入空闲模式时,我仍然可以访问网络并可以将数据发送到我的服务器。打瞌睡模式文档说明了如何强制应用程序进入空闲状态,我相当确定这是打瞌睡模式的同义词。然而,这应该是一个限制,所以我不知道它是如何工作的。
是的,Doze 会忽略您的唤醒锁。但是,使用 setExactAndAllowWhile Idle,您将在正确的时间开始工作,并且您将有 10 秒 window 来执行您希望的任何处理。
如果设备处于打瞌睡模式,WakeLock
对您没有多大帮助。如果您使用 AlarmManager.ELAPSED_REALTIME_WAKEUP
或 AlarmManager.RTC_WAKEUP
作为闹钟 type
,setExactAndAllowWhileIdle
将唤醒您的设备。
但是,从 Android 12 起,您需要 SCHEDULE_EXACT_ALARM
permission to set exact alarms. And if you are planning to release the app to PlayStore there are some acceptable use cases for setting an exact alarm。确保您的应用符合这些政策。
似乎有一些与主题相关的问题,但我还没有找到明确的yes/no答案。
我有一个调用 setExactAndAllowWhileIdle
来启动 BroadcastService 的前台服务。下面是广播接收器中的代码。
public class StepCountUpdaterAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myExampleApp::UpdateSteps");
wakeLock.acquire(3);
StepCounterHandler handler = StepCounterHandler.getInstance();
new TaskRunner().executeAsync(
new SetStepsForDay(SaveSharedPreference.getMemberId(context),
handler.getCumulativeSteps()),result -> {
handler.setAlarm(context);
if(isTimeToReset())
handler.resetStepsCounter();
});
wakeLock.release();
}
在 setExactAndAllowWhileIdle
documentation 中指出:
When the alarm is dispatched, the app will also be added to the system's temporary power exemption list for approximately 10 seconds to allow that application to acquire further wake locks in which to complete its work.
但在打瞌睡模式下 documentation 它指出这是一个限制:
The system ignores wake locks.
这是否意味着 setExactAndAllowWhileIdle
在 Doze 模式下发出的警报提供的 10 秒 window 中获取 3 分钟的部分唤醒锁定实际上是无用的,还是可以正常工作?
在我的例子中,广播接收器将通过该异步任务将数据发送到我的远程服务器,然后它会再次设置警报并重置我的步数计数器。这行得通吗?如果行不通,在打瞌睡模式下发送网络请求并执行后续代码的替代方案是什么?
编辑:通过调试我的应用程序进行的测试表明,当强制设备进入空闲模式时,我仍然可以访问网络并可以将数据发送到我的服务器。打瞌睡模式文档说明了如何强制应用程序进入空闲状态,我相当确定这是打瞌睡模式的同义词。然而,这应该是一个限制,所以我不知道它是如何工作的。
是的,Doze 会忽略您的唤醒锁。但是,使用 setExactAndAllowWhile Idle,您将在正确的时间开始工作,并且您将有 10 秒 window 来执行您希望的任何处理。
如果设备处于打瞌睡模式,WakeLock
对您没有多大帮助。如果您使用 AlarmManager.ELAPSED_REALTIME_WAKEUP
或 AlarmManager.RTC_WAKEUP
作为闹钟 type
,setExactAndAllowWhileIdle
将唤醒您的设备。
但是,从 Android 12 起,您需要 SCHEDULE_EXACT_ALARM
permission to set exact alarms. And if you are planning to release the app to PlayStore there are some acceptable use cases for setting an exact alarm。确保您的应用符合这些政策。