代码之家  ›  专栏  ›  技术社区  ›  ViciDroid

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

  •  14
  • ViciDroid  · 技术社区  · 7 年前

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

    之前,我的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. 即使我听了 “android.intent.action.BOOT_已完成”

    我如何创建一个自定义广播接收器,接收隐式广播以在针对Android O(8.0)时触发警报?有人能给我一个代码示例或文档链接吗。Time或任何其他闹钟应用程序在瞄准O时如何工作?

    2 回复  |  直到 7 年前
        1
  •  29
  •   Larry Schiefer    7 年前

    稍微修改一下你的代码,使广播显式而不是隐式,你会没事的(假设 this 是一个 Activity Context ):

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

    奥利奥的限制是开放的 含蓄的 Intent 通过指定接收广播的类进行广播。

        2
  •  1
  •   Cícero Moura    6 年前

    如果你们习惯于检查警报是否已经注册,请不要忘记在验证中执行同样的操作:

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