So with Android 13 we get the following warning when using the following method:
context.registerReceiver(
/* receiver = */ receiver,
/* filter = */ intentFilter,
)
receiver is missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag for unprotected broadcasts registered for an IntentFilter that cannot be inspected by lint
It's known that we have the following new method from ContextCompat
class which requires us to set ContextCompat.RECEIVER_EXPORTED
or ContextCompat.RECEIVER_NOT_EXPORTED
ContextCompat.registerReceiver(
/* context = */ context,
/* receiver = */ receiver,
/* filter = */ intentFilter,
/* flags = */ ContextCompat.RECEIVER_EXPORTED
)
ContextCompat.RECEIVER_EXPORTED
means the following:
Flag for registerReceiver: The receiver can receive broadcasts from other Apps. Has the same behavior as marking a statically registered receiver with "exported=true"
ContextCompat.RECEIVER_NOT_EXPORTED
means the following:
Flag for registerReceiver: The receiver cannot receive broadcasts from other Apps. Has the same behavior as marking a statically registered receiver with "exported=false"
I need to subscribe for the following broadcast actions:
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_POWER_DISCONNECTED
Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_HEADSET_PLUG
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_ACL_DISCONNECTED
I found out that for the following broadcast actions I can subscribe only if I specify ContextCompat.RECEIVER_EXPORTED
:
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_ACL_DISCONNECTED
And for the following broadcast actions I can subscribe with both ContextCompat.RECEIVER_NOT_EXPORTED
and ContextCompat.RECEIVER_EXPORTED
Intent.ACTION_POWER_CONNECTED
Intent.ACTION_POWER_DISCONNECTED
Intent.ACTION_BATTERY_CHANGED
Intent.ACTION_HEADSET_PLUG
What's the difference and I how will I know it if I don't test it like this?
So Bluetooth broadcast actions are considered as "Other Apps" and power/battery/headset_plug boradcast actions are considered as "System" and that's why they don't require ContextCompat.RECEIVER_EXPORTED
and can work with just ContextCompat.RECEIVER_NOT_EXPORTED
?
But then I checked the following link https://developer.android.com/about/versions/12/reference/broadcast-intents-31
and found out that Bluetooth broadcast actions are also considered as "System" ones... Though it's System Broadcast Intents (API Level 31)
, I could not find a page with higher API level, there are only 30 and 31 pages
Is this a bug in Android or what am I missing? I need to subscribe to all these broadcast actions and I thought that they are all "system" ones, they are not from some third party apps, so that's why I wanted to use ContextCompat.RECEIVER_NOT_EXPORTED
for each one but then I found out that in this case I can't subscribe to Bluetooth broadcast actions
p.s. tested on a build with 33 target/compile API
Exception for receivers that receive only system broadcasts If your app is registering a receiver only for system broadcasts through Context#registerReceiver methods, such as Context#registerReceiver(), then it shouldn't specify a flag when registering the receiver
So it means if we register for system broadcasts only then we can continue using Context.registerReceiver()
instead of ContextCompat.RECEIVER_EXPORTED
But still there will be the following warning:
I have already downloaded the latest studio...
Android Studio Hedgehog | 2023.1.1
But it's fine, it just mentions potentional problems when using non-system broadcasts with no flags.
So we should keep in mind that RECEIVER_NOT_EXPORTED
won't work for all system broadcasts, so better register it without flags (or use it with RECEIVER_EXPORTED
) and for some reason RECEIVER_NOT_EXPORTED
still works for some system broadcasts...
Also here it says we can use RECEIVER_EXPORTED
for system and other apps' broadcasts: