带有广播接收器和隐式广播禁令的Android 8.0 Oreo AlarmManager

Vic*_*oid 14 android broadcastreceiver android-broadcast

我有通过报警管理器设置的关键提醒(它的功能与闹钟应用程序相同).

以前我的Android Manifest中有以下内容:

    <receiver android:name="com.example.app.AlarmReceiver" >
        <intent-filter>
            <action android:name="${packageName}.alarm.action.trigger"/>
        </intent-filter>
    </receiver>
Run Code Online (Sandbox Code Playgroud)

广播接收器:

public class AlarmReceiver extends BroadcastReceiver {

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

}
Run Code Online (Sandbox Code Playgroud)

如何设置警报:

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);
      }
}
Run Code Online (Sandbox Code Playgroud)

使用Android 8.0,我不能再使用Manifest中定义的隐式广播.那很好,给出的替代方法是手动注册它,如下所示:

final BroadcastReceiver receiver = new AlarmReceiver();
final IntentFilter intentFilter = new IntentFilter(ALARM_RECEIVER_INTENT_TRIGGER);
context.registerReceiver(receiver, intentFilter);
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎不合逻辑.

  1. 警报接收器将与上下文的生命周期相关联.当由于内存压力或设备重启而导致应用程序被杀死时,这会导致问题.我每次都需要触发警报,因为它们对用户的健康至关重要.

  2. 即使我听"android.intent.action.BOOT_COMPLETED"并注册我的闹钟接收器,应用程序很快就会被杀死并且不会发出警报.我也没有看到我的警报

    adb shell dumpsys警报

如何创建一个自定义广播接收器,在接收Android O(8.0)时接收隐式广播以触发警报?有人可以通过代码示例或链接到文档来启发我.Timely或任何其他闹钟应用程序在定位O时如何运作?

Lar*_*fer 27

稍微修改你的代码,使广播显而易见而不是隐含,你会没事(假设this是Activity参考或其他Context):

Intent intent = new Intent(ALARM_RECEIVER_INTENT_TRIGGER);
intent.setClass(this, AlarmReceiver.class);
Run Code Online (Sandbox Code Playgroud)

Oreo中的限制是关于隐式广播Intent注册,也就是说你发送广播只会指定动作,类别或数据.您可以通过指定要接收广播的类来使其成为显式广播.

  • 您在清单中的注册很好(我假设您的清单中的常量“ ALARM_RECEIVER_INTENT_TRIGGER”是字符串“ com.example.app.alarm.action.trigger”),尽管您可能应该添加一个“ android:export =条目中的“ false”`可防止其他应用尝试向接收方发送广播,这可能会使您感到混乱。 (2认同)