Grokking Android

Getting Down to the Nitty Gritty of Android Development

Android Quick Tip: Enabling and Disabling BroadcastReceivers at Runtime

By 6 Comments

BroadcastReceivers are good when you want to be notified about system events. But sometimes you do need to know about an event only once or for a short period of time.

A dynamically registered receiver doesn’t cut it because the Activity and it’s dynamically registered broadcast receiver might long be dead when the event occurs. The only way to achieve this is by enabling and disabling broadcast receivers in your code.

Enabling or Disabling BroadcastReceivers

You enable or disable receivers by using methods of the PackageManager class. With this class you can enable and disable app components at runtime:

PackageManager pm = getPackageManager();
ComponentName compName = 
      new ComponentName(getApplicationContext(), 

There are three states the PackageManager offers for this:

Supported states of setComponentEnabledSetting()
COMPONENT_ENABLED_STATE_DEFAULT Sets the state to the manifest file value

By default the PackageManager kills your app immediately, since a component state change could lead to unpredictable situations. The flag DONT_KILL_APP prevents this from happening and is safe to use for BroadcastReceivers. Of course if you do not use the DONT_KILL_APP-flag, you will spot your mistake even with the most cursory of testings 🙂

Disabling BroadcastReceivers by default

If you want to enable your receiver at runtime, you can set the state to disabled initially. You can do so in the manifest file:

   android:enabled="false" >
   <!– your intent filter –>

When to use this

The basic reason why you should do this, is that you want to preserve valuable resources on your user’s devices. You do not want to drain the battery by running code that is not relevant to your user. Most often you can achieve this by using a dynamically registered receiver. But this does not always work.

Three examples where you should explicitly use the PackageManager-solution presented above:

1. You might need to know about the next boot, but only the next one. In this case you cannot use a dynamically registered receiver. You have to use a statically registered one. But you do not want to run it on every boot completion. Which means that you have to disable the receiver after it’s first run.

2. If one or more receivers depend on the state of a specific system service you can disable all of them for as long as the necessary service is not in the desired state. This could be true for network connectivity, while waiting for a GPS fix, for missing Bluetooth availabilty and such.

3. You intend to use notifications – but only if the app is not currently active. In this case your BroadcastReceiver has to be enabled by default. But you would disable it in your Activities’ onResume() method and re-enable it in the onPause() method.

See also Reto Meier’s blog post about location-based apps and have a thorough look at the accompanying source code. He covered these topics initially in his talk at Google’s IO 2011. I highly recommend to watch the video of this talk. It’s definitely a good watch!

Wolfram Rittmeyer lives in Germany and has been developing with Java for many years.

In recent years he shifted his attention to Android and blogs about anything interesting that came up while developing for Android.

You can find him on Google+ and Twitter.

6 thoughts on “Android Quick Tip: Enabling and Disabling BroadcastReceivers at Runtime”

  1. can this be exec as an intent in such apps as Tasker or Llama?

  2. Thanks for the information. Really helped me for my Application Development.

  3. Hi, can you tell me how to cancel a broadcast receiver. What I want to do, app start scanning when button is pressed, reads 25 time rssi of device and saves in database, This part I have done. I am finished with the broadcast receiver but don’t know how to cancel it, App just crashes when I hit back button. Any Ideas?

    1. The BroadcastReceiver ends as soon as you have finished onReceive().

      If you are using startWakefulService(), you have to call YourBroadcastReceiver.completeWakefulIntent(intent) at the end – preferably in a finally-block.

  4. Hi,
    I have a question on setComponentEnabledSetting() API of PackageManager.

    I have a application deveoped for Tablets. I’m disabling the component using pm.setComponentEnabledSetting(new ComponentName(PACKAGE, CLASS),

    Now, when the app starts, I don’t see the component.
    But, when I create a new user in the tablet and switches to that user account, I could see the component back. Even though I try to force disable the component, the logs shows that the component is disabled for user Id 0, though the user Id of the new user is not 0.

    01-28 00:07:10.823 3255 4519 D PackageManager: setEnabledSetting : userId = 0 packageName = XXXX cmp = XXXX newState = 2 callingPackage = 1001

    can you please help me resolve the issue?


    1. I would need some more sources to properly understand what’s happening. Android’s implementation of PackageManager (ApplicationPackageManager) does pass the userId on. So there must be something wrong in your code. Move this to SO, add more explanation and code and leave a comment with the URL of that SO thread here.

Leave a Reply

Your email address will not be published. Required fields are marked *