web-dev-qa-db-ja.com

Android 8.0ブロードキャストレシーバーと暗黙のブロードキャスト禁止を備えたOreo AlarmManager

アラームマネージャーを介して設定される重要なアラームがあります(アラームクロックアプリケーションと同じように機能する必要があります)。

以前は、Android Manifest:

    <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. "Android.intent.action.BOOT_COMPLETED"を聞いてアラームレシーバーを登録しても、その直後にアプリが終了し、アラームは発生しません。アラームも表示されません

    adb Shell dumpsysアラーム

Android O(8.0)をターゲットにしながら、暗黙のブロードキャストを受信して​​アラームを発するカスタムブロードキャストレシーバーを作成するにはどうすればよいですか?コード例またはドキュメントへのリンクを教えてください。またはOをターゲットにした他の目覚まし時計アプリの機能は?

12
ViciDroid

コードを少し修正して、ブロードキャストを暗黙的ではなく明示的にし、問題ないことを確認します(thisActivity参照またはその他のContextであると仮定します)。

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

Oreoの制限は暗黙的 broadcast Intent登録にあります。つまり、送信するのはブロードキャストで、アクション、カテゴリ、または指定されたデータのみが送信されます。ブロードキャストを受信するクラスを指定することで、それをexplicitブロードキャストにします。

25
Larry Schiefer

アラームがすでに登録されているかどうかを確認するのに慣れている場合は、この確認で同じことを忘れないでください:

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;
}
1
Cícero Moura