Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android adding DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION in release build

After building my application with api-level 33, android is adding new permission in the merged manifest

    <permission android:name="com.my.package.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
    <uses-permission android:name="com.my.package.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>

I have a broadcast receiver, is this permission have anything to do with this? should I change any code? Does anybody know the reason this has been added?

        <receiver android:enabled="true" android:exported="true" android:name="com.my.package.EventReceiver">
            <intent-filter>
                <action android:name="com.my.package.event"/>
            </intent-filter>
        </receiver>
```
like image 205
nima moradi Avatar asked Sep 08 '25 14:09

nima moradi


1 Answers

From https://developer.android.google.cn/about/versions/13/features#runtime-receivers:

Safer exporting of context-registered receivers

To help make runtime receivers safer, Android 13 introduces the ability for your app to specify whether a registered broadcast receiver should be exported and visible to other apps on the device. On previous versions of Android, any app on the device could send an unprotected broadcast to a dynamically-registered receiver unless that receiver was guarded by a signature permission.

This exporting configuration is available on apps that do at least one of the following:

  • Use the ContextCompat class from version 1.9.0 or higher of the AndroidX Core library.
  • Target Android 13 or higher.

This node in AndroidManifest.xml is a configuration for Safer exporting of context-registered receivers, ContextCompat needs to use this permission to handle broadcast receiver.

Once the necessary conditions are met, it can be used like this.For more details, please refer to the documentation

Adding dependencies in Gradle.

dependencies {
    val core_version = "1.9.0"
    implementation("androidx.core:core:$core_version")
}

In app code:

// Create an instance of BroadcastReceiver.
val br: BroadcastReceiver = MyBroadcastReceiver()
// Create an instance of IntentFilter.
val filter = IntentFilter(APP_SPECIFIC_BROADCAST)
// Choose whether the broadcast receiver should be exported and visible to other apps on the device. If this receiver is listening for broadcasts sent from the system or from other apps—even other apps that you own—use the RECEIVER_EXPORTED flag. If instead this receiver is listening only for broadcasts sent by your app, use the RECEIVER_NOT_EXPORTED flag.
val listenToBroadcastsFromOtherApps = false
val receiverFlags = if (listenToBroadcastsFromOtherApps) {
    ContextCompat.RECEIVER_EXPORTED
} else {
    ContextCompat.RECEIVER_NOT_EXPORTED
}
// Register the receiver by calling registerReceiver():
ContextCompat.registerReceiver(context, br, filter, receiverFlags)

If you don't need to use this feature and want to remove this node in AndroidManifest.xml, you can do so:

<uses-permission
    android:name="${applicationId}.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"         
    tools:node="remove" />

Write the above code to AndroidManifest.xml, DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION will be removed when the manifest is merged

like image 140
Ketal Avatar answered Sep 10 '25 04:09

Ketal