因此,对于 Android 13,我们在使用以下方法时会收到以下警告:
context.registerReceiver(
/* receiver = */ receiver,
/* filter = */ intentFilter,
)
接收器缺少 RECEIVER_EXPORTED 或 RECEIVER_NOT_EXPORTED 标志 对于为 IntentFilter 注册的未受保护的广播,该 IntentFilter 不能 通过 lint 检查
众所周知,我们在
ContextCompat
类中有以下新方法,需要我们设置 ContextCompat.RECEIVER_EXPORTED
或 ContextCompat.RECEIVER_NOT_EXPORTED
ContextCompat.registerReceiver(
/* context = */ context,
/* receiver = */ receiver,
/* filter = */ intentFilter,
/* flags = */ ContextCompat.RECEIVER_EXPORTED
)
ContextCompat.RECEIVER_EXPORTED
的含义如下:
registerReceiver 的标志:接收者可以接收来自 其他应用。与标记静态注册具有相同的行为 带有“exported=true”的接收器
ContextCompat.RECEIVER_NOT_EXPORTED
的含义如下:
registerReceiver 的标志:接收器无法接收来自 其他应用。与标记静态注册具有相同的行为 带有“exported=false”的接收器
我需要订阅以下广播操作:
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_POWER_DISCONNECTED
Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_HEADSET_PLUG
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_ACL_DISCONNECTED
我发现对于以下广播操作,只有在我指定的情况下才能订阅
ContextCompat.RECEIVER_EXPORTED
:
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_ACL_DISCONNECTED
对于以下广播操作,我可以同时订阅
ContextCompat.RECEIVER_NOT_EXPORTED
和 ContextCompat.RECEIVER_EXPORTED
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_POWER_DISCONNECTED
Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_HEADSET_PLUG
有什么区别,如果我不这样测试我怎么知道呢?
因此,蓝牙广播操作被视为“其他应用程序”,电源/电池/耳机_插头广播操作被视为“系统”,这就是为什么它们不需要
ContextCompat.RECEIVER_EXPORTED
并且可以仅与ContextCompat.RECEIVER_NOT_EXPORTED
一起使用?
但后来我检查了以下链接https://developer.android.com/about/versions/12/reference/broadcast-intents-31
发现蓝牙广播动作也被认为是“系统”…虽然是
System Broadcast Intents (API Level 31)
,但我找不到API级别更高的页面,只有30和31页
这是 Android 中的错误还是我错过了什么?我需要订阅所有这些广播操作,我认为它们都是“system”的,它们不是来自某些第三方应用程序,所以这就是为什么我想为每个操作使用
ContextCompat.RECEIVER_NOT_EXPORTED
,但后来我发现在这种情况下我无法订阅蓝牙广播操作
附注在具有 33 个目标/编译 API 的构建上进行了测试
基于 https://developer.android.com/about/versions/14/behavior-changes-14#system-broadcasts
仅接收系统广播的接收器的例外情况如果您 应用程序正在注册一个接收器,仅用于系统广播 Context#registerReceiver方法,例如Context#registerReceiver(), 那么在注册接收器时不应该指定标志
所以这意味着如果注册系统广播那么我们可以继续使用
Context.registerReceiver()
而不是ContextCompat.RECEIVER_EXPORTED