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

Why is doze mode not affecting the AlarmManager setExact() function?

我正在尝试测试 Android 应用程序在 OS 进入打盹模式时的行为。我正在使用 gennymotion 模拟器 运行 Android API 25. 应用程序使用类型为 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 命令将模拟器置于 IDLE 状态,如下所示:-

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

我什至用

仔细检查过
adb shell dumpsys deviceidle get deep

问题来了:-

即使设备处于空闲状态,我仍然能够看到警报启动的 IntentService(MyService)。这些是 logcat 结果:-

    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

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

Standard AlarmManager alarms (including setExact() and setWindow()) are deferred to the next maintenance window.

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

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

以下问题可能重复,但未按要求给出答案:-

P.S:-

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

我发现了问题:

首先,当我在模拟器中测试我的应用程序时(我在我的应用程序中使用了 genymotion案例).

然后我决定使用物理 phone 即 HTC Desire 530,但结果仍然相同。这是我感到沮丧的地方,直到我在 HTC 官方 documentation support page 中发现了一些非常有趣的东西,那就是:

The phone exits from Doze mode when:

You plug in the power adapter and charge the phone.

There's movement, such as when you pick up the phone.

An alarm clock goes off at your set time.

我想知道第 3 点是否是打瞌睡模式不影响 alarmmanager setExact 方法的原因。所以我在另一个 phone 即 OPPO A3s 中测试了我的应用程序。 这是运行预期的地方!

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

所以我得出的结论是:-

  • HTC 可能修改了打瞌睡模式的行为? (因为 android 正式 限制 alarmmanager setExact 在休眠模式下执行,而 HTC 没有)。这个(也许是天真的)假设背后的原因是我在一些 android phone 中看到了一些不标准的行为,比如即使设备关闭,警报也会响起!
  • 最后但同样重要的是,永远不要相信你的模拟器 :p

P.S:

如果你想知道为什么我对这整件事如此关心,那是因为我正在开发一个闹钟应用程序并且我正在使用 alarmmanager 来执行基于时间的任务。如果这个问题一直存在,我将无法正确测试我的应用程序(希望你明白我的意思)。

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

更新:-

打瞌睡模式对 alarmmanager setExact() 没有影响,即使我在 HTC Desire 530 中打开电池优化也是如此。