Android AlarmManager并不总是执行BroadcastReceiver

Android AlarmManager并不总是执行BroadcastReceiver,android,broadcastreceiver,alarmmanager,wakelock,Android,Broadcastreceiver,Alarmmanager,Wakelock,所以我有一个广播接收器和报警管理器 假设我创建了这样的待定意图: Intent i; i = new Intent(context, MyReceiver.class); i.setAction(MyReceiver.ACTION_1); i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); pendingIntent1 = PendingIntent.getBroadcast(context, 1, i, PendingIntent.FLAG_UPDATE_

所以我有一个广播接收器和报警管理器

假设我创建了这样的待定意图:

Intent i;
i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_1);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent1 = PendingIntent.getBroadcast(context, 1, i, PendingIntent.FLAG_UPDATE_CURRENT);

i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_2);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent2 = PendingIntent.getBroadcast(context, 2, i, PendingIntent.FLAG_UPDATE_CURRENT);
now = SystemClock.elapsedRealtime();
long time1 = now + 10 * 1000;
long time2 = time1 + 60 * 1000;

am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time1, pendingIntent1);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time2, pendingIntent2);
并按如下方式安排警报:

Intent i;
i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_1);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent1 = PendingIntent.getBroadcast(context, 1, i, PendingIntent.FLAG_UPDATE_CURRENT);

i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_2);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent2 = PendingIntent.getBroadcast(context, 2, i, PendingIntent.FLAG_UPDATE_CURRENT);
now = SystemClock.elapsedRealtime();
long time1 = now + 10 * 1000;
long time2 = time1 + 60 * 1000;

am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time1, pendingIntent1);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time2, pendingIntent2);
我现在体验到,我的广播接收器非常可靠地接收到
动作1
的广播,而
动作2
通常无法发送。因此,
onReceive
很少或从未执行过意图保持动作
action_2
。怎么会这样?我想,
*\u WAKEUP
确保广播仍在进行

[更新日期:2015年9月15日] -出于测试目的,我试图在我的
onReceive
方法中打印一条日志消息。仍然不起作用。 -我已尝试在AlarmManager上使用setExact。仍然不起作用。 -我甚至尝试过使用
WakefulBroadcastReceiver
。仍然不起作用。 -然而,我发现,当设备处于电池充电状态时,它会可靠地唤醒。 什么可能导致此问题?我到处都读到,如果报警管理器通过挂起的意图触发广播接收器,广播接收器保证执行(并且在
onReceive
中不执行太多操作)。我的手机上是否有一些积极的节能政策,而这些政策是我无法真正反对的(如果没有长时间的唤醒锁,请参见评论)


[更新09/19/2015]我刚刚在Google Play上测试了一些闹钟应用程序(),它也不能可靠地唤醒手机。我想,这真的是个错误,不是我的错。我想我会坚持使用唤醒锁解决方案。

我遇到了同样的问题,我找到的解决方案是仅通过操作字符串创建意图,并在清单中注册接收方操作。尝试将意图更改为以下内容:

i = new Intent("com.app.ACTION_ONE");
然后在清单文件中,向接收者添加以下内容:

<intent-filter>
    <action android:name="com.app.ACTION_ONE" />
</intent-filter>

我的猜测是,如果你不向接收者注册至少一个动作,那么当应用程序终止时,接收者就会死亡


希望它能起作用,祝你好运。

你是否注册了广播接收器(或从清单中注册)

上次我使用了几乎相同的方法,但是使用了
AlarmManager.RTC_WAKEUP
-如果您不想从深度睡眠中唤醒设备,请使用
AlarmManager.RTC

long time = System.currentTimeMillis() + 10*1000;
alarmMgr.set(AlarmManager.RTC_WAKEUP, time, alarmIntent);
警报的意图如下:

alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(MyReceiver.class.getName()), PendingIntent.FLAG_CANCEL_CURRENT);

注意以下几点可能是有用的:

  • 您正在使用AlarmManager.set()方法,但该方法不保证发送时间,若您希望在准确的时间触发报警,请使用

  • 你的广播意图对我来说毫无意义。这是含蓄的,但广播不应该如此。这种意图可能是android奇怪行为的原因。如果您希望具有隐式意图,请直接将其发送给处理它的服务。在这种情况下,我建议使用:

    Intent intent = new Intent(Contants.Action1);
    
  • 如果在清单中定义了接收者,则即使应用程序的所有活动都已停止,也会传递意图;如果动态注册了接收者,则它只能在装入它的线程处于活动状态时接收意图

  • 不同版本的Android试图以略微不同的方式优化警报,但目标是同时触发尽可能多的警报,以获得更好的电池性能


  • 所有这些都会让人感到困惑。但是,如果接收器注册正确,则可以保证发送意图。

    查看索尼设备上的“耐力模式”设置。 尝试禁用“耐力模式”,或在“耐力模式”启用时将您的应用程序添加到允许的应用程序白名单中


    希望这有帮助。

    showAt的值是多少?对不起,已修复。它应该是
    time1
    。该应用程序基本上是在屏幕关闭一段时间后(这里是10秒)显示一个对话框(在一个透明的活动中),如果屏幕关闭太久(这里是10+60=70秒),则再次隐藏它。我现在通过获得一个唤醒锁解决了我的问题,如下所示:
    wakeLock.acquire(time2-now+5000)
    (在上面的示例中,保持手机处于唤醒状态-70秒加上5秒作为缓冲)-然而,我觉得这是一个相当粗糙的解决方案。你怎么认为?它是合法的还是太脏,可能会引起问题?你在测试哪款手机?索尼型号有一个积极的节能模式默认启用,可以阻止服务唤醒。是的,这是一个索尼Xperia Z1紧凑型。。。我想,手动获取带有超时的唤醒锁的方法是最可靠的解决方案,但仍然不起作用。:/另一个旁注:如果我在关闭屏幕后安排第一次广播,例如3秒,它通常会在再次打开屏幕后执行(但我已经等待了大约10秒)。您好,谢谢您的回复。1.我已经使用
    setExact
    Build.VERSION.SDK\u INT>=Build.VERSION\u CODES.KITKAT
    更改了代码。2.我已经使用
    newintent(MyReceiver.ACTION_1)更改了我的代码。3.我的接收者当前已在清单中定义(我尝试了这两种方法)。~~然而,我的经验是,在这一点上,它们不能保证正确交付。我现在把我的问题归咎于索尼严格的节能政策,但我不确定。还可以查看我的编辑:我可以用一个报警应用程序重现这种不良行为。