Fix for java.lang.SecurityException: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver is registered in Flutter (Android)
Image by Cherell - hkhazo.biz.id

Fix for java.lang.SecurityException: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver is registered in Flutter (Android)

Posted on
Table of Contents

If you’re a Flutter developer, you might have encountered the frustrating java.lang.SecurityException error when trying to register a broadcast receiver in your Android app. This error can be a real showstopper, especially if you’re new to Android development. But fear not, dear developer! In this article, we’ll dive into the root cause of this error and provide a comprehensive guide on how to fix it.

In Android, a broadcast receiver is a component that allows your app to listen for system-wide announcements, such as network changes, battery low warnings, or incoming SMS messages. When a broadcast is sent, the receiver is triggered, and your app can respond accordingly.

To register a broadcast receiver, you need to declare it in your AndroidManifest.xml file and specify the actions it should listen for. Here’s an example:

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BATTERY_LOW"/>
    </intent-filter>
</receiver>

In the above example, the MyReceiver class is registered to listen for the android.intent.action.BATTERY_LOW action.

Now, let’s talk about the error that brings us together today. When you try to register a broadcast receiver without specifying the android:exported attribute, you might encounter the following error:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapp, PID: 12345
java.lang.SecurityException: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver is registered
    at android.os.Parcel.readException(Parcel.java:2013)
    at android.os.Parcel.readException(Parcel.java:1959)
    at android.app.ActivityManagerProxy.registerReceiver(ActivityManagerNative.java:4447)
    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1724)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1695)
    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:611)
    ...

This error occurs because the Android system requires you to specify whether your broadcast receiver should be exported or not.

The android:exported attribute determines whether your broadcast receiver should be accessible from other apps. If set to true, your receiver is exported, meaning it can receive broadcasts from other apps. If set to false, your receiver is not exported, and it can only receive broadcasts from within your own app.

In Android 12 (API level 31) and later, you must specify one of the following attributes:

  • android:exported="true": Your receiver is exported and can receive broadcasts from other apps.
  • android:exported="false": Your receiver is not exported and can only receive broadcasts from within your own app.

To fix the error, you simply need to add the android:exported attribute to your broadcast receiver declaration in the AndroidManifest.xml file. Here’s an updated example:

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BATTERY_LOW"/>
    </intent-filter>
</receiver>

In this example, we’ve added the android:exported="true" attribute, specifying that our receiver should be exported and can receive broadcasts from other apps.

If you don’t want your receiver to be exported, you can set the android:exported attribute to false. This is useful when your receiver only needs to listen for broadcasts within your own app.

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="android.intent.action.BATTERY_LOW"/>
    </intent-filter>
</receiver>

In this article, we’ve explored the java.lang.SecurityException error that occurs when registering a broadcast receiver in Flutter (Android) without specifying the android:exported attribute. We’ve learned about the importance of declaring whether your receiver should be exported or not and how to fix the error by adding the necessary attribute to your AndroidManifest.xml file.

Remember, when in doubt, always specify the android:exported attribute to ensure your broadcast receiver behaves as intended. Happy coding!

Attribute Description
android:exported=”true” Specifies that the receiver should be exported and can receive broadcasts from other apps.
android:exported=”false” Specifies that the receiver should not be exported and can only receive broadcasts from within your own app.

If you’re new to Android development, here are some additional resources to help you get started:

Have you encountered this error before? How did you fix it? Share your experience in the comments below!

Frequently Asked Questions

Stuck with the pesky `java.lang.SecurityException` in Flutter? Don’t worry, we’ve got you covered!

What is the `java.lang.SecurityException` in Flutter?

This exception occurs when you’re trying to register a broadcast receiver in your Flutter app without specifying either `RECEIVER_EXPORTED` or `RECEIVER_NOT_EXPORTED` in the AndroidManifest.xml file. It’s a security measure to prevent other apps from sending malicious broadcasts to your app.

How do I fix the `java.lang.SecurityException` in Flutter?

To fix this issue, you need to add the `android:exported` attribute to the `` tag in your `AndroidManifest.xml` file. Set it to `true` if you want to allow other apps to send broadcasts to your receiver, or `false` if you only want to receive broadcasts from within your app.

Where do I add the `android:exported` attribute in my `AndroidManifest.xml` file?

You need to add the `android:exported` attribute to the `` tag that corresponds to the broadcast receiver that’s causing the exception. For example, if you’re using the Flutter Firebase Cloud Messaging (FCM) plugin, you’ll find the `` tag in the `android/app/src/main/AndroidManifest.xml` file.

What happens if I set `android:exported` to `true`?

If you set `android:exported` to `true`, your app will be able to receive broadcasts from other apps. This can be a security risk if you’re not careful, as malicious apps could send malicious broadcasts to your app. However, it’s necessary if you want to receive broadcasts from other apps, such as FCM notifications.

What if I’m still getting the `java.lang.SecurityException` after adding the `android:exported` attribute?

If you’re still getting the exception after adding the `android:exported` attribute, make sure you’ve added it to the correct `` tag in your `AndroidManifest.xml` file. Also, clean and rebuild your Flutter project to ensure that the changes take effect.