如何在打盹模式下使用Android 6.0时使Alarm Manager正常工作?

时间:2015-09-10 03:41:44

标签: 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);

和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);

部分方法已内嵌,方便阅读。

2 个答案:

答案 0 :(得分:34)

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

您是否尝试过使用setAlarmclock()方法代替set()? 它专门设计用于闹钟,并且可以切断打瞌睡。您可以使用一些adb命令手动将手机置于打盹或应用待机状态:https://developer.android.com/preview/features/power-mgmt.html

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

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

答案 1 :(得分:2)

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

对于setExactAndAllowWhileIdle()方法,请从SDK查看以下说明。它不会将手机从打瞌睡中唤醒。

  

当调度警报时,该应用程序也将被添加到   系统的临时白名单大约允许10秒钟   该应用程序获取进一步的唤醒锁定,以完成   它的工作。