Подтвердить что ты не робот

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_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, и он не надежно пробуждает телефон, слишком. Наверное, это действительно ошибка, а не моя вина. Я буду придерживаться решения блокировки слежения, я думаю.

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

Вы зарегистрировали 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);

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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