Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiver not registered exception error?

People also ask

How do I know if my broadcast receiver is registered?

A simple solution to this problem is to call the registerReceiver() in your Custom Application Class. This will ensure that your Broadcast receiver will be called only one in your entire Application lifecycle.


The root of your problem is located here:

 unregisterReceiver(batteryNotifyReceiver);

If the receiver was already unregistered (probably in the code that you didn't include in this post) or was not registered, then call to unregisterReceiver throws IllegalArgumentException. In your case you need to just put special try/catch for this exception and ignore it (assuming you can't or don't want to control number of times you call unregisterReceiver on the same recevier).


Be careful, when you register by

LocalBroadcastManager.getInstance(this).registerReceiver()

you can't unregister by

 unregisterReceiver()

you must use

LocalBroadcastManager.getInstance(this).unregisterReceiver()

or app will crash, log as follow:

09-30 14:00:55.458 19064-19064/com.jialan.guangdian.view E/AndroidRuntime: FATAL EXCEPTION: main Process: com.jialan.guangdian.view, PID: 19064 java.lang.RuntimeException: Unable to stop service com.google.android.exoplayer.demo.player.PlayService@141ba331: java.lang.IllegalArgumentException: Receiver not registered: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 at android.app.ActivityThread.handleStopService(ActivityThread.java:2941) at android.app.ActivityThread.access$2200(ActivityThread.java:148) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1395) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5310) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696) Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:769) at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1794) at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:510) at com.google.android.exoplayer.demo.player.PlayService.onDestroy(PlayService.java:542) at android.app.ActivityThread.handleStopService(ActivityThread.java:2924) at android.app.ActivityThread.access$2200(ActivityThread.java:148)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1395)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5310)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696) 


Use this code everywhere for unregisterReceiver:

if (batteryNotifyReceiver != null) {
    unregisterReceiver(batteryNotifyReceiver);
    batteryNotifyReceiver = null;
}

As mentioned in other answers, the exception is being thrown because each call to registerReceiver is not being matched by exactly one call to unregisterReceiver. Why not?

An Activity does not always have a matching onDestroy call for every onCreate call. If the system runs out of memory, your app is evicted without calling onDestroy.

The correct place to put a registerReceiver call is in the onResume call, and unregisterReceiver in onPause. This pair of calls is always matched. See the Activity lifecycle diagram for more details. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Your code would change to:

SharedPreferences mPref
IntentFilter mFilter;

@Override
public void onCreate(){
    super.onCreate();
    mPref = PreferenceManager.getDefaultSharedPreferences(this);
    mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    filter.addAction(Intent.ACTION_POWER_CONNECTED);
    filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
 }

@Override
public void onResume() {
    registerReceiver(batteryNotifyReceiver,mFilter);
    mPref.registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause(){
     unregisterReceiver(batteryNotifyReceiver, mFilter);
     mPref.unregisterOnSharedPreferenceChangeListener(this);
}

EDIT: This is the answer for inazaruk and electrichead... I had run into a similar issue to them and found out the following...

There is a long-standing bug for this problem here: http://code.google.com/p/android/issues/detail?id=6191

Looks like it started around Android 2.1 and has been present in all of the Android 2.x releases since. I'm not sure if it is still a problem in Android 3.x or 4.x though.

Anyway, this StackOverflow post explains how to workaround the problem correctly (it doesn't look relevant by the URL but I promise it is)

Why does keyboard-slide crash my app?