Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当Android 6.0处于睡眠模式时,如何使Alarm Manager工作?_Android_Alarmmanager_Android 6.0 Marshmallow - Fatal编程技术网

当Android 6.0处于睡眠模式时,如何使Alarm Manager工作?

当Android 6.0处于睡眠模式时,如何使Alarm Manager工作?,android,alarmmanager,android-6.0-marshmallow,Android,Alarmmanager,Android 6.0 Marshmallow,我是谷歌Play上两个闹钟应用程序的开发者。我正试图让他们使用安卓6.0。但是,打瞌睡模式使其不响。我把它们放在白名单上,我把一个前台通知图标放上去,我不确定我还能做什么——在打瞌睡模式下,报警管理器报警仍然被忽略。不过,时钟应用程序(这是一款谷歌Play而非AOSP应用程序)则有所不同。当在时钟应用程序上启用报警时,“adb deviceidle step”将始终显示为“active”,而不会显示为“idle”、“idle_pending”或任何其他内容 Android在这里作弊,给自己的应用

我是谷歌Play上两个闹钟应用程序的开发者。我正试图让他们使用安卓6.0。但是,打瞌睡模式使其不响。我把它们放在白名单上,我把一个前台通知图标放上去,我不确定我还能做什么——在打瞌睡模式下,报警管理器报警仍然被忽略。不过,时钟应用程序(这是一款谷歌Play而非AOSP应用程序)则有所不同。当在时钟应用程序上启用报警时,“adb deviceidle step”将始终显示为“active”,而不会显示为“idle”、“idle_pending”或任何其他内容

Android在这里作弊,给自己的应用程序更多的权力,又名。“拉苹果”?谷歌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.StarTringAlarm()方法的相关部分:


有些方法已内联粘贴以便于阅读。

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

您是否尝试过使用该方法而不是
set()
? 它是专为闹钟而设计的,可能可以避免打瞌睡。有几个adb命令可用于手动将手机置于doze或app待机模式:

如果这无法唤醒你的应用程序,那么surefire方法可以让你无论发生什么都能从睡梦中唤醒手机。在最坏的情况下,您可以使用此方法唤醒您的应用程序,并使用唤醒来安排下一个警报


另一个值得一读的页面是这篇博客文章,其中有关于后台工作和报警的流程图:

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

对于
setExactAndAllowHileId()
方法,请查看SDK中的以下描述。它不会把手机从睡梦中唤醒

发出警报时,应用程序也将添加到 系统的临时白名单大约10秒,以允许 该应用程序将获取更多要完成的唤醒锁 它的工作


让我们有一些片段,可以帮助其他人看到发生了什么。请:-)当然,我会编辑我的回复。它们都是超过20k行的代码,所以我将尝试发布其中一行的相关代码。有趣的是,有关于这一行的帮助吗?使用setAlarmClock()时,这似乎正在工作。当我尝试使用“adb shell deviceidle step”将我的应用程序设置为睡眠模式时,警报将很快响起,它将保持该模式处于活动状态。这非常有用!但是,请参阅此报告,
set[Exact]和allowhileidle()
方法不起作用:-(在Ian Lake的报告中,在内部构建中,
和allowhileidle()
方法在打瞌睡时触发的次数比开发者预览3多得多。从我使用开发者预览3和
setExactAndAllowHileidle()和
setAndAllowHileidle()的测试中
methods,这些警报将在空闲状态下触发,持续约10秒的网络连接时间。此外,它们之间的通话间隔至少为15分钟。但是,从技术上讲,手机在此期间从未脱离空闲模式。
setAlarmClock()
似乎可以将整个手机从空闲模式唤醒,并允许更长的唤醒锁定时间。@Jenix我想我实际上已经检查了源代码。但这是AOSP,因此OEM可能可以将其更改为任何它想要的。没错。从文档:“白名单上的应用程序的作业和同步被延迟,其常规AlarmManager警报不会触发。”@UncaughtException那么我今天如何处理android 6和7的此问题?您能提供任何实施示例吗?如果找到任何解决方案,请与大家分享
    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);