Android 6.0 Doze 模式中的警报管理器问题 [英] Alarm Manager issue in Android 6.0 Doze mode
问题描述
我制作了一个一直运行到 Android 6.0 的应用.我认为是打盹功能导致我的闹钟无法启动.
我使用 sharedpreferences 来处理选项:
//启用夜间模式定时器int sHour = blockerTimerPreferences.getInt("sHour", 00);int sMinute = blockerTimerPreferences.getInt("sMinute", 00);日历 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);
知道这里出了什么问题吗?
这是一款拦截来电的应用.谢谢!
我有 3 个文件(更多但...),例如:
MainActivity(所有代码)CallReceiver(再次触发警报的广播(重启等))CallReceiverService(处理通话/电话状态)
Doze 模式会将您的警报延迟到下一个维护时段.为避免打盹模式阻止您的闹钟,您可以使用 <代码>setAndAllowWhileIdle(), setExactAndAllowWhileIdle()
或 setAlarmClock()
.您将有大约 10 秒的时间来执行您的代码,并设置您的下一个闹钟(不过对于带有 _AndAllowWhileIdle
的方法,每 15 分钟不超过一次)
如果你想测试 Doze 模式,你可以使用 亚行命令:
<块引用>使用 Android 6.0(API 级别 23)或更高版本的系统映像配置硬件设备或虚拟设备.
将设备连接到您的开发机器并安装您的应用.
- 运行您的应用并使其保持活动状态.
关闭设备屏幕.(该应用程序保持活动状态.)通过运行以下命令强制系统在打盹模式下循环:
adb shell dumpsys 电池拔掉
adb shell dumpsys deviceidle 步骤
您可能需要多次运行第二个命令.重复此操作,直到设备状态变为空闲.
- 在您重新激活设备后观察您的应用的行为.确保应用在设备退出 Doze 时正常恢复.
添加 setAlarmClock 示例
不要忘记检查 SDK 级别(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
)
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);Intent intent = new Intent(this, MyAlarmReceiver.class);//或者只是 new Intent() 用于隐式意图//设置动作以知道这是来自闹钟intent.setAction("from.alarm.clock");PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);//5s内报警.am.setAlarmClock(new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + 5000, pi), pi);
I've made an app that always worked until Android 6.0. I think it's the Doze feature that it's not allowing my Alarm to fire.
I use sharedpreferences to handle the options:
//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:
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()
. 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)
If you want to test the Doze mode, you can use ADB command:
Configure a hardware device or virtual device with an Android 6.0 (API level 23) or higher system image.
Connect the device to your development machine and install your app.
- Run your app and leave it active.
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
You may need to run the second command more than once. Repeat it until the device state changes to idle.
- 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
Don't forget to check the SDK level (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);
这篇关于Android 6.0 Doze 模式中的警报管理器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!