Android 8.0 Oreo AlarmManager 带有广播接收器和隐式广播禁令
Android 8.0 Oreo AlarmManager with broadcast receiver and implicit broadcast ban
我有通过闹钟管理器设置的重要提醒(它的功能应该与闹钟应用程序相同)。
以前我的 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);
我觉得这不合逻辑。
警报接收器将绑定到上下文的生命周期。当应用程序由于内存压力或设备重新启动而被终止时,这会导致问题。我需要每次都触发警报,因为它们对用户的健康至关重要。
即使我收听 "android.intent.action.BOOT_COMPLETED" 并注册我的警报接收器,该应用程序很快就会被终止并且不会触发任何警报。我也没有通过
看到我的闹钟
adb shell dumpsys 报警
如何创建一个自定义广播接收器来接收隐式广播以在瞄准 Android O (8.0) 时触发警报?有人可以通过代码示例或 link 文档启发我。针对 O 时,Timely 或任何其他闹钟应用如何运行?
稍微修改你的代码,使广播显式而不是隐式,你会没事的(假设 this
是一个 Activity
参考或其他一些 Context
):
Intent intent = new Intent(ALARM_RECEIVER_INTENT_TRIGGER);
intent.setClass(this, AlarmReceiver.class);
Oreo 中的限制是隐式 广播Intent
注册,也就是说您向它发送的广播只会指定动作、类别或数据。通过指定接收广播的 class 使其成为 explicit 广播。
如果你们习惯了检查警报是否已经被注册,请不要忘记在这个验证中做同样的事情:
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;
}
我有通过闹钟管理器设置的重要提醒(它的功能应该与闹钟应用程序相同)。
以前我的 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);
我觉得这不合逻辑。
警报接收器将绑定到上下文的生命周期。当应用程序由于内存压力或设备重新启动而被终止时,这会导致问题。我需要每次都触发警报,因为它们对用户的健康至关重要。
即使我收听 "android.intent.action.BOOT_COMPLETED" 并注册我的警报接收器,该应用程序很快就会被终止并且不会触发任何警报。我也没有通过
看到我的闹钟adb shell dumpsys 报警
如何创建一个自定义广播接收器来接收隐式广播以在瞄准 Android O (8.0) 时触发警报?有人可以通过代码示例或 link 文档启发我。针对 O 时,Timely 或任何其他闹钟应用如何运行?
稍微修改你的代码,使广播显式而不是隐式,你会没事的(假设 this
是一个 Activity
参考或其他一些 Context
):
Intent intent = new Intent(ALARM_RECEIVER_INTENT_TRIGGER);
intent.setClass(this, AlarmReceiver.class);
Oreo 中的限制是隐式 广播Intent
注册,也就是说您向它发送的广播只会指定动作、类别或数据。通过指定接收广播的 class 使其成为 explicit 广播。
如果你们习惯了检查警报是否已经被注册,请不要忘记在这个验证中做同样的事情:
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;
}