Android 6.0 处于打盹模式时如何让闹钟管理器工作?

Posted

技术标签:

【中文标题】Android 6.0 处于打盹模式时如何让闹钟管理器工作?【英文标题】:How to make Alarm Manager work when Android 6.0 in Doze mode? 【发布时间】:2015-12-06 04:52:15 【问题描述】:

我是 Google Play 上两个闹钟应用的开发者。我试图让他们使用 android 6.0。但是,打瞌睡模式使它不会响铃。我把它们放在白名单上,我放了一个前台通知图标,我不确定我还能做什么 - 在打盹模式下,警报管理器警报仍然被忽略。但是,时钟应用程序(它是一个 Google Play 而不是 AOSP 应用程序)是不同的。在时钟应用上启用闹钟后,“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);

为了便于阅读,部分方法已被内联粘贴。

【问题讨论】:

让我们有一些 sn-ps 可以帮助其他人了解正在发生的事情。请:-) 当然,我会编辑我的回复。它们都是 20k+ 行代码,所以我将尝试为其中之一发布相关行。 有趣,有什么帮助吗? alarm clocks riddle 【参考方案1】:

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”将我的应用程序设置为打盹模式时,警报将很快响起,它将保持模式处于活动状态。 这很有帮助!但是请参阅此报告code.google.com/p/android-developer-preview/issues/… set[Exact]AndAllowWhileIdle() 方法不起作用。 :-( 在plus.google.com/+AndroidDevelopers/posts/94jCkmG4jff 中,Ian Lake 报告说,在内部构建中,AndAllowWhileIdle() 方法在打盹期间触发的次数比开发者预览版 3 的预期要高得多。 根据我使用 Developer Preview 3 和 setExactAndAllowWhileIdle()setAndAllowWhileIdle() 方法进行的测试,这些警报在空闲状态下触发大约 10 秒网络连接。此外,它们可能仅相隔至少 15 分钟。但是,从技术上讲,手机在此期间从未退出空闲模式。 setAlarmClock() 似乎将整个手机从空闲模式唤醒,并允许更长的唤醒锁。 @Jenix 我想​​我实际上检查了源代码。但这是 AOSP,因此 OEM 可以随意更改。【参考方案2】:

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

对于setExactAndAllowWhileIdle() 方法,请查看SDK 中的以下描述。它不会将手机从打盹中唤醒。

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

【讨论】:

没错。来自文档:“白名单应用的作业和同步被推迟,并且它的常规 AlarmManager 警报不会触发。” @UncaughtException 那么我今天如何为 android 6 和 7 处理这个问题?你能提供任何实现的例子吗? 如果您找到任何解决方案,请分享 ***.com/questions/32627342/…

以上是关于Android 6.0 处于打盹模式时如何让闹钟管理器工作?的主要内容,如果未能解决你的问题,请参考以下文章

Android的Doze模式

如何以编程方式关闭棉花糖设备中特定应用程序的打盹模式

打盹/待机功能如何影响位置更新?

在 Genymotion 中测试打盹功能(Android 6.0 Marshmallow)

如何在 Android 上测试打盹模式?

鹅厂专家详解Android N适配要点 | 腾讯优测干货分享