简体   繁体   English

Android 6.0 Doze模式下的Alarm Manager问题

[英]Alarm Manager issue in Android 6.0 Doze mode

I've made an app that always worked until Android 6.0. 我制作的应用程序一直有效,直到Android 6.0。 I think it's the Doze feature that it's not allowing my Alarm to fire. 我认为这是Doze功能,它不允许我的警报发射。

I use sharedpreferences to handle the options: 我使用sharedpreferences来处理选项:

//ENABLE NIGHT MODE TIMER
    int sHour = blockerTimerPreferences.getInt("sHour", 00);
    int sMinute = blockerTimerPreferences.getInt("sMinute", 00);

    Calendar sTime = Calendar.getInstance();
    sTime.set(Calendar.HOUR_OF_DAY, sHour);
    sTime.set(Calendar.MINUTE, sMinute);

    Intent enableTimer = new Intent(context, CallReceiver.class);
    enableTimer.putExtra("activate", true);
    PendingIntent startingTimer = PendingIntent.getBroadcast(context, 11002233, enableTimer, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager sAlarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    sAlarm.setRepeating(AlarmManager.RTC_WAKEUP,
            sTime.getTimeInMillis(),
            AlarmManager.INTERVAL_DAY, startingTimer);

Any clue of whats wrong here? 这里有什么错误吗?

This is an app to block calls. 这是一个阻止通话的应用。 Thank you! 谢谢!

EDIT: I have 3 files (more but...) like: 编辑:我有3个文件(更多但是......)像:

MainActivity (All code)
CallReceiver (Broadcast that triggers the alarm again (reboot etc))
CallReceiverService (Handles the call / phone state)

The Doze mode will delay your alarm until the next maintenance window. 打盹模式会将警报延迟到下一个维护窗口。 To avoid the Doze mode to block your alarm, you can use setAndAllowWhileIdle() , setExactAndAllowWhileIdle() or setAlarmClock() . 要避免打盹模式阻止警报,可以使用setAndAllowWhileIdle()setExactAndAllowWhileIdle()setExactAndAllowWhileIdle() setAlarmClock() You will have about 10s to execute your code, and set your next alarm (not more than once per 15min for methods with _AndAllowWhileIdle though) 您将有大约10秒来执行您的代码,并设置您的下一个警报(对于具有_AndAllowWhileIdle方法,每15分钟不超过一次)

If you want to test the Doze mode, you can use ADB command : 如果要测试打盹模式,可以使用ADB命令

  1. Configure a hardware device or virtual device with an Android 6.0 (API level 23) or higher system image. 使用Android 6.0(API级别23)或更高系统映像配置硬件设备或虚拟设备。

  2. Connect the device to your development machine and install your app. 将设备连接到开发计算机并安装应用程序。

  3. Run your app and leave it active. 运行您的应用并将其保持活动状态。
  4. Shut off the device screen. 关闭设备屏幕。 (The app remains active.) Force the system to cycle through Doze modes by running the following commands: (应用程序保持活动状态。)通过运行以下命令强制系统在打盹模式下循环:

    adb shell dumpsys battery unplug

    adb shell dumpsys deviceidle step

  5. You may need to run the second command more than once. 您可能需要多次运行第二个命令。 Repeat it until the device state changes to idle. 重复此过程,直到设备状态变为空闲。

  6. Observe the behavior of your app after you reactivate the device. 重新激活设备后,请观察应用程序的行为。 Make sure the app recovers gracefully when the device exits Doze. 当设备退出打盹时,请确保应用程序正常恢复。

Edit: Add setAlarmClock example 编辑:添加setAlarmClock示例

Don't forget to check the SDK level ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) 不要忘记检查SDK级别( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class); //or just new Intent() for implicit intent 
//set action to know this come from the alarm clock
intent.setAction("from.alarm.clock");
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Alarm fire in 5s.
am.setAlarmClock(new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + 5000, pi), pi);

If the device is in doze mode, you need to use one of these API: setExactAndAllowWhileIdle or setAndAllowWhileIdle . 如果设备处于打盹模式,则需要使用以下API之一: setExactAndAllowWhileIdlesetAndAllowWhileIdle

Note that there is no API for waking the device up while in doze mode for a repeating alarm, so if you need a repeating alarm to wake the device while in doze, you have to use the APIs above and re-arm the timer at every occurrence of the timer firing. 请注意,在打盹模式下,对于重复警报,没有用于唤醒设备的API,因此如果您在打盹时需要重复警报来唤醒设备,则必须使用上面的API并在每次重新启动计时器发生计时器发射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM