24

I have a BroadcastReceiver for one time use.

I'm registering it in an Activity. I can't put the unregisterReceiver() in onPause because it has to stay running even when the activity is paused or destroyed.

I want the BroadcastReceiver to unregister itself when it is done, something like this:

public class SmsReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
           // do some code..
           context.unregisterReceiver(this)
        }
}

But it causes an Exception: Receiver not registered.

blahdiblah
  • 30,909
  • 18
  • 92
  • 149
shaimagz
  • 1,235
  • 4
  • 16
  • 39

7 Answers7

26

A BroadcastReceiver only exists during the execution of its onReceive() method. So, this evaluates to a throw-away instance every time the broadcast is fired/received. See Broadcast Receiver Lifecycle. For dynamically registering/unregistering of BroadcastReceivers, you have to remember the instance of your receiver in onPause() to register it again during onResume().

Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
tichy
  • 503
  • 4
  • 10
  • 2
    A BroadcastReceiver object follows the same garbage collection rules as any other object. There's no special "throw-away instance". Referencing `this` in `onReceive` gives the same result a reference from when the object was created (try it). The documentation is talking about the receiver's *process* being killed, not anything at the level of the receiver object. – blahdiblah Jan 10 '17 at 00:06
10

I know this question already has an answer But try this Code

This code is for BatteryInfo. And it did work.

private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context arg0, Intent intent) {
        // TODO Auto-generated method stub
        int level = intent.getIntExtra("level", 0);
        Log.i("Battery", String.valueOf(level) + "%");
        arg0.unregisterReceiver(mBatInfoReceiver);
    }

};

//Below code is the Code which attaches the reciever put this code in which ever place you want. 

this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(
                Intent.ACTION_BATTERY_CHANGED));

Reference for Attaching StackOverFlow / Tutorial

Community
  • 1
  • 1
MDMalik
  • 3,889
  • 2
  • 23
  • 39
3

Just add a method call to the Activity you registered it in, and in that method, unregister the receiver. That way you know its job has been done.

However, the receiver won't work if the activity is paused or destroyed anyways. You'd have to declare it in the manifest or else register it in a long-running service to keep it working outside of an activity's lifetime. As far as I know, you can't unregister a receiver declared in the manifest because you don't get the instance it's registered with. But the method call to the Service to unregister it should work.

If you just need a worker for one-time use, declare an exported IntentService in the manifest with the action you're broadcasting. That IntentService will be started when the intent is received and given the intent that started it, and then when it's done its job, it will stop on its own.

Austin B
  • 1,492
  • 1
  • 13
  • 25
2

I have met the same problem, actually, the correct answer is LocalBroadcastManager.getInstance(context).unregisterReceiver(this); but not context.unregisterReceiver(this)

0

Maybe the issue is that you are trying to unregister the receiver from the receiver's context, instead of the context where it was originally registered.

hvuoltee
  • 408
  • 4
  • 8
0

Have you tried unregistering the reciver from a Service/Activity? Maybe there is some issue if you call it from the reciever to unregister itself.

mdelolmo
  • 6,277
  • 3
  • 38
  • 58
0

Probably you have already unregistered it elsewhere in your program, however unlikely this may sound. Maybe somewhere before your context.unregisterReceiver, but in the onReceive method you invoke an action, that results in unregeistering the receiver prior to reaching context.unregisterReceiver.

Just make sure you are unregistering the receiver from as less places as possible, preferably - exactly one.

Alex Lockwood
  • 81,274
  • 37
  • 197
  • 245
George
  • 3,587
  • 8
  • 28
  • 47
  • 2
    But if I unregistered it already, how come it still gets to that point and runs the unregister method? It's not possible... – shaimagz Feb 10 '11 at 15:09