为什么打瞌睡模式不会影响 AlarmManager setExact() 函数?



我正在尝试测试我的Android应用程序在操作系统进入打瞌睡模式时的行为。我正在使用运行Android API 25的gennymotion模拟器。应用程序使用类型为 RTC_WAKEUP 的 setExact 方法通过 AlarmManager 启动 IntentService。我将闹钟设置为在 1 分钟后触发(仅用于测试目的(。

这是意图服务代码(MyService.java(:-

public class MyService extends IntentService {
public static final String TAG = "noor";
@Override
public void onHandleIntent(Intent intent) {
for (int i = 1; i <= 10; i++) {
Log.d(TAG, "i: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}

这是警报管理器代码:-

AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 101, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (60 * 1000),pendingIntent);
}

}

只是为了确保我通过运行建议的 dumpsys 命令成功地将模拟器置于空闲状态,如下所示:-

adb shell dumpsys deviceidle enable
adb shell dumpsys battery unplug
adb shell dumpsys deviceidle force-idle

我什至通过使用仔细检查

adb shell dumpsys deviceidle get deep

现在问题来了:-

即使设备处于空闲状态,我仍然能够看到警报启动的意图服务(MyService(。 这些是日志猫的结果:-

2019-10-04 01:42:20.842 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 1
2019-10-04 01:42:21.843 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 2
2019-10-04 01:42:22.845 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 3
2019-10-04 01:42:23.856 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 4
2019-10-04 01:42:24.857 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 5
2019-10-04 01:42:25.859 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 6
2019-10-04 01:42:26.860 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 7
2019-10-04 01:42:27.861 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 8
2019-10-04 01:42:28.862 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 9
2019-10-04 01:42:29.863 1818-1922/com.example.android.sunshineweatherapp D/noor: i: 10

根据文档,这不应该是预期的行为:-

标准 AlarmManager 警报(包括 setExact(( 和 setWindow((( 推迟到下一个维护时段。

所以我也期待相反的情况(因为如果设备处于打瞌睡模式,则不应触发 setExact((。我什至在真实设备(运行Android Marshmallow(上对此进行了测试,并获得了相同的结果。

这是一个错误吗?还是我错过了什么?

以下问题可能是重复的,但答案没有按预期给出:- Android M(预览版(打瞌睡模式和警报管理器

附言:-

这是我第三次在这个平台上发布这个问题,因为我没有得到任何答案。我在整个互联网上找不到任何帮助(reddit,androidcentral,quora,coderanch(。
我必须制作一个闹钟应用程序,如果此问题仍然存在,我将无法正确测试行为。

我发现了问题:

首先,当我在模拟器中测试我的应用程序时,打瞌睡模式不会影响alarmmanager setExact(( 函数(我在我的情况下使用了 genymotion(。

然后我决定使用实体手机,即HTC Desire 530,但结果仍然相同。这就是我感到沮丧的地方,直到我在HTC官方文档支持页面中发现了一些非常有趣的东西,那就是:

在以下情况下,手机将退出低电耗模式:

插入电源适配器并为手机充电。

有动作,比如当你拿起电话时。

闹钟在您设定的时间响起。

我想知道第 3 点是否可能是打瞌睡模式不影响警报管理器 setExact 方法的原因。所以我在另一部手机(即OPPO A3s(上测试了我的应用程序。这是事情按预期运行的地方!

setExact 方法没有在打瞌睡模式下运行,而当我退出打瞌睡模式时它确实运行了!而setExactAndAllowWhileIdle((就像它在文档中写的那样运行。

所以我得出的结论是:

  • HTC 可能修改了打瞌睡模式的行为?(自安卓正式 限制警报管理器设置在 HTC 时在打瞌睡模式下精确执行 不会(。这个(也许是幼稚的(假设背后的原因是我已经在一些安卓手机中看到了一些不标准的行为,比如即使设备关机,警报也会响起!
  • 最后但并非最不重要的一点是,永远不要相信您的模拟器:p

附言:

如果您想知道为什么我如此关注整个事情,那是因为我正在开发一个警报应用程序,并且我正在使用 AlarmManager 执行基于时间的任务。如果这个问题持续存在,我将无法正确测试我的应用程序(希望你明白我的意思(。

Android的背景限制和电池优化使简单的事情变得复杂。

更新:-

打瞌睡模式对警报管理器setExact((没有影响,即使我在HTC Desire 530中打开了电池优化。

最新更新