2015-08-12 4 views
13

Итак, у меня есть BroadcastReceiver и AlarmManager.AlarmManager не всегда выполняет BroadcastReceiver

Скажем, я создаю 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 уверен, что трансляции доставляются в любом случае?

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

+0

Какая ценность 'showAt'? –

+0

Oups извините, исправлено. Он должен был быть «time1». Приложение в основном показывает диалог (в прозрачной активности) через некоторое время, когда экран погас (здесь 10 секунд) и спрятал его снова, если экран был слишком длинным (здесь 10 + 60 = 70 секунд). – flxapps

+0

Теперь я решил проблему, получив блокировку следа: 'wakeLock.acquire (time2 - now + 5000);' (поддержание пробуждения телефона для - в верхнем примере - 70 секунд плюс 5 секунд в качестве буфера) - Однако я чувствую, что это довольно хакерское решение. Как вы думаете? Является ли это законным или слишком грязным, что может вызвать проблемы? – flxapps

ответ

6

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

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

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

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

Я думаю, если вы не зарегистрировать по крайней мере, 1 действие на recevier он просто умирает, когда прикладные программы заканчиваются.

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

+0

Все еще не работает. :/Еще одно примечание: если я планирую первую трансляцию, например, Через 3 секунды после выключения экрана он часто запускается после включения экрана снова (после того, как я уже ждал, например, 10 секунд). – flxapps

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); 

The alarmIntent как:

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

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

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

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

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

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

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

+0

Здравствуйте, спасибо за ваш ответ. 1. Я уже изменил свой код с помощью 'setExact' для' Build.VERSION.SDK_INT> = Build.VERSION_CODES.KITKAT'. 2. Я уже изменил свой код с помощью 'new Intent (MyReceiver.ACTION_1);'. 3. Мой приемник в настоящее время определен в манифесте (я попробовал оба).~~ Ну, однако, мой опыт заключается в том, что они не гарантированно доставлены правильно. В настоящее время я обвиняю в некоторых строгих правилах энергосбережения от Sony по моей проблеме, но я не уверен, хотя. Также проверьте мое редактирование: я могу воспроизвести неправильное поведение с помощью приложения для сигнализации. – flxapps

0

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

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

Смежные вопросы