所以我有一个BroadcastReceiver和AlarmManager。
假设我像这样创建Pending Intents:
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);
我现在正在经历我的广播接收器非常可靠地获得ACTION_1
的广播,而ACTION_2
通常没有被传送。因此onReceive
很少或永远不会执行持有动作ACTION_2
的意图。怎么回事?我想,*_WAKEUP
确保广播正在传送?
[2015年9月15日更新]
- 出于测试目的,我试图在onReceive
方法中打印出日志消息。还是行不通。
- 我现在尝试在AlarmManager上使用setExact。还是行不通。
- 我甚至尝试过使用WakefulBroadcastReceiver
。还是行不通。
- 但我发现,当处于电池充电状态时,设备可靠地唤醒。
可能导致此问题的原因是什么? 我已经读到,如果警报管理员通过未决意图触发广播接收器,保证会执行广播接收器(并且没有做太多的事情)在onReceive
)。我的手机上是否有一些积极的节能政策,我无法真正反对(没有获得长唤醒锁定,请参阅评论)?
[2015年9月19日更新]我刚刚在Google Play上测试了一些闹钟应用程序(https://play.google.com/store/apps/details?id=com.alarmclock.xtreme.free),它也无法可靠地唤醒手机。我猜,这真的是一个错误而不是我的错。我想,我会坚持使用唤醒锁解决方案。
答案 0 :(得分:6)
我遇到了同样的问题,我发现的解决方案是仅通过操作字符串创建意图,并在清单中注册该接收器操作。尝试将意图改为这样的事情:
i = new Intent("com.app.ACTION_ONE");
然后在您的清单文件中添加以下内容:
<intent-filter>
<action android:name="com.app.ACTION_ONE" />
</intent-filter>
我的猜测是,如果你没有向接收者注册至少1个动作,那么当应用程序终止时,他就会死掉。
希望它有效,祝你好运。
答案 1 :(得分:2)
您是否注册了BroadcastReceiver(或来自Manifest)?
registerReceiver(new MyReceiver(), new IntentFilter(MyReceiver.class.getName()));
我上次使用的方法几乎相同,但使用AlarmManager.RTC_WAKEUP
- 如果您不想将设备从深度睡眠状态唤醒,请使用AlarmManager.RTC
long time = System.currentTimeMillis() + 10*1000;
alarmMgr.set(AlarmManager.RTC_WAKEUP, time, alarmIntent);
alarmIntent like:
alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(MyReceiver.class.getName()), PendingIntent.FLAG_CANCEL_CURRENT);
答案 2 :(得分:1)
很少有事情值得注意:
您正在使用AlarmManager.set()方法,如果您希望在准确时间触发警报,则无法保证交付时间使用AlarmManager.setExact()
你广播的意图对我来说没有意义。这是隐含的,但广播不应该是。这样的意图可能会引起奇怪的Android行为。如果您想要隐式意图,请将其直接发送给处理它的服务。在接收器的情况下,我建议使用:
Intent intent = new Intent(Contants.Action1);
如果你的接收器是以明显意图定义的,那么即使你的应用程序的所有活动都已经死了,如果接收器动态地注册它,它只能在它被装箱的线程存活时才能接收意图。
不同版本的Android尝试以稍微不同的方式优化警报,但目标是同时触发尽可能多的警报,以达到更好的电池性能。
所有这些都可能令人困惑。但是如果接收器正确注册,保证会传递意图。
答案 3 :(得分:0)
在sony设备上查看“Stamina Mode”的设置。 尝试停用Stamina模式或将您的应用添加到耐力模式开启时允许的应用白名单中。
希望这有帮助。