Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct pattern for registering a receiver?

Tags:

android

I need to register a receiver. I have been using the following pattern:

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(myReceiver, new IntentFilter(...));
}

@Override 
protected void onPause() {
    super.onPause();
    unregisterReceiver(myReceiver);
}

private BroadcastReceiver myReceiver = new BroadcastReceiver() {
    ...
});

I'm getting crash reports from marketplace about my unregisterReceiver() call:

java.lang.IllegalArgumentException: Receiver not registered

I thought this could not be possible, but it seems this is the correct pattern instead:

private Intent mIntent;

@Override
protected void onResume() {
    super.onResume();
    if (mIntent == null) {
        mIntent = registerReceiver(myReceiver, new IntentFilter(...));
    }
}

@Override 
protected void onPause() {
    super.onPause();
    if (mIntent != null) {
        unregisterReceiver(myReceiver);
        mIntent = null;
    }
}

private BroadcastReceiver myReceiver = new BroadcastReceiver() {
    ...
});

Is the above the correct pattern? I guess it's possible for registration to fail, and we have to keep the result from registerReceiver(), and check it in onPause() before making the call to unregister()?

Thanks


I am basing the change off of this question: Problem with BroadcastReceiver (Receiver not registered error)

I've only ever seen the first pattern above, never one where you check the intent response - any clarification would be great.

like image 521
user291701 Avatar asked Oct 05 '11 17:10

user291701


People also ask

How do I know if my broadcast receiver is registered?

registerReceiver(BroadcastReceiver,IntentFilter) */ public Intent register(Context context, IntentFilter filter) { try { // ceph3us note: // here I propose to create // a isRegistered(Contex) method // as you can register receiver on different context // so you need to match against the same one :) // example by ...

Where do I register and unregister broadcast receiver?

Receiver can be registered via the Android manifest file. You can also register and unregister a receiver at runtime via the Context. registerReceiver() and Context. unregisterReceiver() methods.


1 Answers

Is the above the correct pattern?

No, this isn't necessarily going to work. From the docs for registerReceiver(...)...

Returns The first sticky intent found that matches filter, or null if there are none.

In other words even if the call to register the receiver is successful, it may still return null if there are no sticky broadcasts for that intent filter.

My approach would be to simply use a boolean and a try/catch block...

private boolean isReceiverRegistered;

@Override
protected void onResume() {
    super.onResume();
    if (!isReceiverRegistered) {
        registerReceiver(myReceiver, new IntentFilter(...));
        isReceiverRegistered = true;
    }
}

@Override 
protected void onPause() {
    super.onPause();
    if (isReceiverRegistered) {
        try {
            unregisterReceiver(myReceiver);
        } catch (IllegalArgumentException e) {
            // Do nothing
        }
        isReceiverRegistered = false;
    }
}
like image 99
Squonk Avatar answered Sep 20 '22 04:09

Squonk