如何在Doze模式下使用Android 6.0时使Alarm Manager工作?

use*_*060 48 android alarmmanager android-6.0-marshmallow

我是Google Play上两个闹钟应用的开发者.我想让他们使用Android 6.0.但是,打盹模式使它们不响.我把它们放在白名单上,我放了一个前景通知图标,我不知道我还能做什么 - 当处于打盹模式时,警报管理器警报仍然被忽略.然而,时钟应用程序(这是一个Google Play而不是AOSP应用程序)是不同的.当在Clock应用程序上启用闹钟时,"adb deviceidle step"将始终显示为"active"且永远不会"idle","idle_pending"或其他任何内容.

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);
Run Code Online (Sandbox Code Playgroud)

和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);
}
Run Code Online (Sandbox Code Playgroud)

以及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);
Run Code Online (Sandbox Code Playgroud)

一些方法已被内联粘贴,以便于阅读.

ccp*_*ark 35

Doze和App Standby肯定会改变警报和唤醒锁的行为,但它们对你来说绝对不是世界末日!

您是否尝试过使用该方法setAlarmclock()而不是set()?它专为闹钟而设计,可能能够通过打瞌睡.您可以使用一些adb命令手动将手机置于打盹或应用待机模式: https //developer.android.com/preview/features/power-mgmt.html

如果那不能唤醒你的应用程序,那么万无一失的方法setExactAndAllowWhileIdle()就是将手机从打瞌睡中唤醒,无论如何.最糟糕的情况是,您可以使用此方法唤醒应用程序并使用唤醒来安排下一个警报.

另一个值得一读的页面是这篇博客文章及其背景工作和警报的流程图:https://plus.google.com/+AndroidDevelopers/posts/GdNrQciPwqo

  • 这似乎是有效的,使用setAlarmClock().当我尝试使用"adb shell deviceidle step"将我的应用程序设置为打盹模式时,警报将很快响起,它将使模式保持在ACTIVE状态. (4认同)
  • 从我使用Developer Preview 3和`setExactAndAllowWhileIdle()`和`setAndAllowWhileIdle()`方法的测试中,这些警报_will_在空闲状态期间触发,持续时间约为10秒的网络连接.此外,他们可能只被称为至少相隔15分钟.但是,在此期间,手机从未在技术上退出空闲模式.`setAlarmClock()`似乎将整个手机从空闲模式唤醒,并允许更长的唤醒锁. (4认同)
  • 这很有帮助!但请参阅此报告https://code.google.com/p/android-developer-preview/issues/detail?id=2225,`set [Exact] AndAllowWhileIdle()`方法不起作用.:-( (3认同)