AlarmManager не всегда выполняет BroadcastReceiver

Итак, у меня есть BroadcastReceiver и AlarmManager.

Предположим, что я создаю ожидающие намерения так:

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_1 достаточно надежно, в то время как ACTION_2 часто не доставляется. Поэтому onReceive редко или никогда не выполняется с намерением, содержащим действие ACTION_2 . Как это получается? Я думал, *_WAKEUP гарантирует, что трансляции будут доставлены в любом случае?

[Обновление 09/15/2015] – В целях тестирования я пытаюсь распечатать сообщение журнала в моем методе onReceive . Все еще не работает. – Я попытался использовать setExact в AlarmManager сейчас. Все еще не работает. – Я даже пытался использовать WakefulBroadcastReceiver . Все еще не работает. – Однако я узнал, что устройство надежно просыпается, когда заряжается в заряженном состоянии. Что может вызвать эту проблему? Я читал везде, что приемники вещания гарантированно выполняются, если они запускаются диспетчером аварийных сигналов через ожидающее намерение (и не делают слишком много вещей в onReceive ). Возможно, у меня есть какая-то агрессивная политика энергосбережения на моем телефоне, с которой я не могу работать (без приобретения длинного следящего замка, см. Комментарии)?

[Обновление 09/19/2015] Я только что проверил приложение для будильника ( https://play.google.com/store/apps/details?id=com.alarmclock.xtreme.free ) в Google Play, и он не Надежно просыпается и телефон. Наверное, это действительно ошибка, а не моя вина. Полагаю, я буду придерживаться решения блокировки следа.

Solutions Collecting From Web of "AlarmManager не всегда выполняет BroadcastReceiver"

Я столкнулся с той же проблемой, решение, которое я нашел, – это создать намерение только по строке действия и зарегистрировать это действие приемника в манифесте. Попробуйте изменить намерение на что-то вроде этого:

 i = new Intent("com.app.ACTION_ONE"); 

То в вашем файле манифеста добавьте в свой приемник следующее:

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

Я предполагаю, что если вы не зарегистрируете хотя бы одно действие на получателя, он просто умрет, когда завершение работы приложения прекратится.

Надеюсь, он работает, удачи.

Вы зарегистрировали BroadcastReceiver (или из манифеста)?

  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 = PendingIntent.getBroadcast(this, 0, new Intent(MyReceiver.class.getName()), PendingIntent.FLAG_CANCEL_CURRENT); 

Есть несколько вещей, которые можно было бы отметить:

  1. Вы используете метод AlarmManager.set (), который не гарантирует время доставки, если вы хотите, чтобы будильник срабатывал при точном использовании времени AlarmManager.setExact ()

  2. Вы трансляции намерения не имеет смысла для меня. Он неявный, но трансляции не должны быть. Такое намерение может быть резонансом для странного поведения андроида. Если вы хотите иметь неявное намерение, отправьте его непосредственно в службу обработки. В случае приемника я бы рекомендовал использовать:

     Intent intent = new Intent(Contants.Action1); 
  3. Если ваш получатель определен в манифестных намерениях, будет доставлен, даже если все действия вашего приложения будут мертвы, если ресивер зарегистрирован динамически, он может получать намерения только тогда, когда поток на whitch, который был упакован, остается в живых.

  4. Различные версии Android пытаются оптимизировать сигналы тревоги несколько иначе, но цель состоит в том, чтобы запускать столько сигналов тревоги, сколько возможно в то же самое время, чтобы добиться более высокой производительности батареи.

Все это может быть довольно запутанным. Но намерения гарантированно будут доставлены, если приемник зарегистрирован правильно.

Посмотрите настройки «Режим выносливости» на ваших устройствах sony. Попробуйте отключить режим выносливости или добавить приложение в белый список приложений, разрешенных при включенном режиме выносливости.

Надеюсь это поможет.