如何在Android 6.0处于打盹模式时使闹钟pipe理器工作?

我是Google Play上两个闹钟应用的开发者。 我正试图让他们使用Android 6.0。 但是,打盹模式使它不会响。 我把它们放在白名单上,我把一个前台通知图标,我不知道还有什么我可以做的 – 当在打盹模式,警报pipe理器警报仍然被忽略。 时钟应用程序(这是一个谷歌播放,而不是AOSP应用程序),但是,是不同的。 当时钟应用程序启用闹钟时,“adb deviceidle step”将始终为“活动”,永不“空闲”,“闲置”或其他任何内容。

Android在这里作弊,给自己的应用程序更多的权力,又名。 “拉苹果”? Google Play上的所有闹钟应用程序都将无法使用吗? 这里有一种担心,这些都是优质的应用程序,每个都需要一年的兼职开发时间,对我来说是很大的收入来源。 任何线索我如何能得到这些工作将是一个巨大的帮助。

设置AlarmManager的意图:

Intent intent = new Intent(context, ReceiverAlarm.class); if (android.os.Build.VERSION.SDK_INT >= 16) { intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); } amSender = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT); //FLAG_CANCEL_CURRENT seems to be required to prevent a bug where the intent doesn't fire after app reinstall in KitKat am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, scheduleToTime+1, amSender); 

和ReceiverAlarm类:

 public class ReceiverAlarm extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (wakeLock == null) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle); wakeLock.acquire(); } X.alarmMaster.startRingingAlarm(true); } 

以及X.alarmMaster.startRingingAlarm()方法的相关部分:

  if (wakeLock == null) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle); wakeLock.acquire(); } if (screenWakeLock == null) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); screenWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, Theme.appTitle+" scr"); screenWakeLock.acquire(); } Intent alarmIntent = new Intent(Intent.ACTION_VIEW); alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); alarmIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); alarmIntent.setClass(context, ActivityAlarmAlarm.class); context.startActivity(alarmIntent); 

其中一些方法已被内联粘贴,以方便阅读。

Solutions Collecting From Web of "如何在Android 6.0处于打盹模式时使闹钟pipe理器工作?"

打瞌睡和应用待命肯定会改变警报和唤醒的行为,但绝对不是你的世界末日!

你是否尝试过使用方法setAlarmclock()而不是set() ? 它是专门为闹钟devise的,也许能够打通瞌睡。 您可以使用几个adb命令手动将手机置于睡眠或应用程序待机模式: https : //developer.android.com/preview/features/power-mgmt.html

如果这不能唤醒你的应用程序,那么肯定会有方法setExactAndAllowWhileIdle()被devise用来唤醒手机,不pipe是什么。 最糟糕的情况,你可以用这种方法唤醒你的应用程序,并使用唤醒安排下一个警报。

另一个值得一读的页面是这个博客的stream程图,用于后台工作和报警: https : //plus.google.com/+AndroidDevelopers/posts/GdNrQciPwqo

也许帮助你:

如果我们的应用程序的目标应用程序的API级别低于19(KitKat),则预定的警报将在警报时间正好运行。 对于针对KitKat或更高版本的应用程序,时间表被认为是不精确的,系统可能会重新sorting或分组闹钟,以最大限度地减less唤醒和节省电池。

在API Level 23之后,Android开发团队进一步推进,在Android系统上推出打盹模式,以减less设备从电源适配器拔出时的耗电量,静止不动,长时间不被用户使用。

打盹系统将尝试降低设备的唤醒频率,推迟后台作业,networking更新,同步以及我们的宝贵警报,直到设备退出打盹模式或重复维护时段运行,以执行挂起的作业,某些警报或与networking。 在维护窗口结束后,如果在此期间不使用,设备将再次进入打盹模式:

在这里输入图像说明

打盹模式可能会影响您的应用程序,并会延迟您的警报,直到维护窗口进入,除非您使用方法setAndAllowWhileIdle()和setExactAndAllowWhileIdle()允许在深度空闲状态执行您的报警。

而且,在长时间不活动的情况下,打盹模式维护窗口运行的次数会减less,所以这个新机制对我们调度的影响会增加,从而在报警时间引起更多不可预知的抖动。

在打盹模式下,应用程序也不允许访问networking,WakeLocks被忽略,Wi-Fi扫描不被执行。

如果我们需要精确的时间安排,并针对棉花糖或更高版本,则应使用在API级别23引入的新setExactAndAllowWhileIdle()方法:

 am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pending); 

注意

Android系统具有防止滥用频率过高的精确警报的保护function。 AlarmManager只唤醒设备并每分钟发送一次警报,在低功耗模式下,每15分钟可以低至一次。

如果您的应用程序的目标版本是KitKat(API Level 19)和Marshmallow(API Level 23)之间的版本,那么setExact方法对于时间精度来说就足够了:

 am.setExact(AlarmManager.RTC_WAKEUP, time, pending); 

但是在我们试图调用它之前,我们需要检查这些方法是否存在。 否则,我们的应用程序将在早期API级别下运行时崩溃。 让我们画出我们新的精确报警代码:

 if (Build.VERSION.SDK_INT >= 23) { // Wakes up the device in Doze Mode am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pending); } else if (Build.VERSION.SDK_INT >= 19) { // Wakes up the device in Idle Mode am.setExact(AlarmManager.RTC_WAKEUP, time, pending); } else { // Old APIs am.set(AlarmManager.RTC_WAKEUP, time, pending); } 

这将在所有平台的特定时间发出警报。

asynchronousandroid编程

将应用程序置于白名单中只允许networking处于打盹模式。 AlarmManager不受白名单的影响。

对于setExactAndAllowWhileIdle()方法,请从SDK中查看以下描述。 它不会打醒电话。

当警报发出时,应用程序也将被添加到系统的临时白名单约10秒,以允许该应用程序获得进一步的唤醒锁,以完成其工作。