Android 8.0 Oreo AlarmManager с широковещательным приемником и неявным запретом вещания


У меня есть критические напоминания, которые устанавливаются через менеджер будильников (он должен работать так же, как приложение будильника).

Ранее в моем Манифесте Android было следующее:

    <receiver android:name="com.example.app.AlarmReceiver" >
        <intent-filter>
            <action android:name="${packageName}.alarm.action.trigger"/>
        </intent-filter>
    </receiver>

Широковещательный приемник:

public class AlarmReceiver extends BroadcastReceiver {

  @Override public void onReceive(
      final Context context,
      final Intent intent) {
// WAKE LOCK
// BUILD NOTIFICATION etc...
  }

}

Как устанавливается сигнализация:

final PendingIntent operation = PendingIntent.getBroadcast(
          mContext,
          requestCode,
          intent,
          PendingIntent.FLAG_CANCEL_CURRENT);

      if (PlatformUtils.hasMarshmallow()) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, operation);

      } else {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, operation);
      }
}

С Android 8.0 я больше не могу использовать неявную трансляцию, как определено в Манифесте. Это нормально, альтернативный вариант-зарегистрировать его вручную следующим образом:

final BroadcastReceiver receiver = new AlarmReceiver();
final IntentFilter intentFilter = new IntentFilter(ALARM_RECEIVER_INTENT_TRIGGER);
context.registerReceiver(receiver, intentFilter);

Это не кажется логично для меня.

  1. Приемник сигнала тревоги будет привязан к времени жизни контекста. Это вызывает проблему, когда, скажем, приложение отключается из-за нехватки памяти или при перезапуске устройства. Мне нужно, чтобы мои сигналы тревоги срабатывали каждый раз, когда они критичны для здоровья пользователя.

  2. Даже если я слушаю "андроида.намерение.действие.BOOT_COMPLETED " и зарегистрируйте мой приемник сигнала тревоги приложение будет убито вскоре после этого, и сигнал тревоги не сработает. Я тоже не вижу мой будильник через

    Adb shell dumpsys alarm

Как создать пользовательский широковещательный приемник, который получает неявную широковещательную передачу, чтобы включить сигнал тревоги, ориентируясь на Android O (8.0)? Кто-нибудь может просветить меня примером кода или ссылкой на документацию. Как работает приложение "своевременный" или любое другое приложение "будильник", ориентируясь на O?

2 10

2 ответа:

Слегка измените свой код, чтобы сделать трансляцию явной, а не неявной, и вы будете в порядке (предполагая, что this является ссылкой Activity или какой-то другой Context):

Intent intent = new Intent(ALARM_RECEIVER_INTENT_TRIGGER);
intent.setClass(this, AlarmReceiver.class);

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

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

public boolean isAlarmBroadcastRegistered(Context context, String action, Class clazz) {
    Intent intent = new Intent(action);
    intent.setClass(context, clazz);
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE) != null;
}