Receptor no registrado error de excepción?

En mi consola de desarrollador, la gente sigue informando un error que no puedo reproducir en ningún teléfono que tengo. Una persona dejó un mensaje diciendo que lo tiene cuando intenta abrir la pantalla de configuración de mi servicio de batería. Como puede ver en el error, dice que el receptor no está registrado.

java.lang.RuntimeException: Unable to stop service .BatteryService@4616d688: java.lang.IllegalArgumentException: Receiver not registered: com.app.notifyme.BatteryService$BatteryNotifyReceiver@4616d9d0 at android.app.ActivityThread.handleStopService(ActivityThread.java:3164) at android.app.ActivityThread.access$3900(ActivityThread.java:129) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2173) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4701) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Receiver not registered:com..BatteryService$BatteryNotifyReceiver@4616d9d0 at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:805) at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:859) at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331) at com.app.notifyme.BatteryService.onDestroy(BatteryService.java:128) at android.app.ActivityThread.handleStopService(ActivityThread.java:3150) 

Me registro en mi onCreate

 @Override public void onCreate(){ super.onCreate(); SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); registerReceiver(batteryNotifyReceiver,filter); pref.registerOnSharedPreferenceChangeListener(this); } 

Anular el registro en onDestroy y también con un oyente de preferencia

  @Override public void onDestroy(){ super.onDestroy(); unregisterReceiver(batteryNotifyReceiver); } 

y este es mi receptor en el servicio

 private final class BatteryNotifyReceiver extends BroadcastReceiver { boolean connected; @Override public void onReceive(Context context, Intent intent) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor edit = prefs.edit(); updatePreferences(prefs); level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){ connected = true; }else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)){ connected = false; }else if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){ if(level  40){ edit.putBoolean("first", false).commit(); edit.putBoolean("second", false).commit(); edit.putBoolean("third", false).commit(); edit.putBoolean("fourth",false).commit(); edit.putBoolean("fifth", false).commit(); } if(level == 40){ if(!first){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("first", true).commit(); } }else if(level == 30){ if(!second){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("second", true).commit(); } }else if(level == 20){ if(!third){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("third", true).commit(); } }else if(level == 15){ if(!fourth){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("fourth", true).commit(); } }else if(level == 5){ if(!fifth){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("fifth", true).commit(); } } lastLevel = temp; } } Intent i = new Intent(context,BatteryNotifyReceiver.class); context.startService(i); } } 

¿Alguna idea de por qué recibirían ese error?

La raíz de su problema se encuentra aquí:

  unregisterReceiver(batteryNotifyReceiver); 

Si el receptor ya no estaba registrado (probablemente en el código que no incluyó en esta publicación) o no estaba registrado, entonces call para unregisterReceiver IllegalArgumentException arroja IllegalArgumentException . En su caso, solo necesita poner try / catch especial para esta excepción e ignorarlo (suponiendo que no puede o no quiere controlar la cantidad de veces que llama a unregisterReceiver en el mismo recevier).

Use este código en todas partes para anular el registro de Receptor:

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

Tenga cuidado, cuando se registra por

 LocalBroadcastManager.getInstance(this).registerReceiver() 

no puedes anular el registro por

  unregisterReceiver() 

debes usar

 LocalBroadcastManager.getInstance(this).unregisterReceiver() 

o la aplicación se bloqueará, registra de la siguiente manera:

09-30 14: 00: 55.458 19064-19064 / com.jialan.guangdian.view E / AndroidRuntime: EXCEPCIÓN FATAL: proceso principal: com.jialan.guangdian.view, PID: 19064 java.lang.RuntimeException: no se puede detener el servicio com.google.android.exoplayer.demo.player.PlayService@141ba331: java.lang.IllegalArgumentException: Receiver no registrado: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 en android.app.ActivityThread. handleStopService (ActivityThread.java:2941) en android.app.ActivityThread.access $ 2200 (ActivityThread.java:148) en android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1395) en android.os.Handler.dispatchMessage ( Handler.java:102) en android.os.Looper.loop (Looper.java:135) en android.app.ActivityThread.main (ActivityThread.java:5310) en java.lang.reflect.Method.invoke (Método nativo) en java.lang.reflect.Method.invoke (Method.java:372) en com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:901) en com.android.internal.os.ZygoteInit.main (ZygoteInit.java:696) Causado por: java.lang.IllegalArgumentException: Receptor no registrado: com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 en android.app.LoadedApk.forgetReceiverDispatcher (LoadedApk.java: 769) en android.app.ContextImpl.unregisterReceiver (ContextImpl.java:1794) en android.content.ContextWrapper.unregisterReceiver (ContextWrapper.java:510) en com.google.android.exoplayer.demo.player.PlayService.onDestroy (PlayService .java: 542) en android.app.ActivityThread.handleStopService (ActivityThread.java:2924) en android.app.ActivityThread.access $ 2200 (ActivityThread.java:148) en android.app.ActivityThread $ H.handleMessage (ActivityThread.java : 1395) en android.os.Handler.dispatchMessage (Handler.java:102) en android.os.Looper.loop (Looper.java:135) en android.app.ActivityThread.main (ActivityThread.java:5310) en java .lang.reflect.Method.invoke (Método nativo) en java.lang.reflect.Method.invoke (Method.java:372) en com.android.internal.os.ZygoteInit $ MethodA ndArgsCaller.run (ZygoteInit.java:901) en com.android.internal.os.ZygoteInit.main (ZygoteInit.java:696)

Como se menciona en otras respuestas, se lanza la excepción porque cada llamada a registerReceiver no se corresponde exactamente con una llamada para unregisterReceiver de unregisterReceiver . Por qué no?

Una Activity no siempre tiene una llamada onDestroy coincidente para cada llamada onCreate . Si el sistema se queda sin memoria, su aplicación se desaloja sin llamar a onDestroy .

El lugar correcto para poner una llamada registerReceiver es en la llamada onResume , y unregisterReceiver de onPause en onPause . Este par de llamadas siempre coincide. Vea el diagtwig del ciclo de vida de la actividad para más detalles. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Su código cambiaría a:

 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); } 

EDITAR: Esta es la respuesta para inazaruk y electrichead … me encontré con un problema similar y descubrí lo siguiente …

Aquí hay un error de larga data para este problema: http://code.google.com/p/android/issues/detail?id=6191

Parece que comenzó en Android 2.1 y ha estado presente en todos los lanzamientos de Android 2.x desde entonces. No estoy seguro de si todavía es un problema en Android 3.xo 4.x.

De todos modos, esta publicación de StackOverflow explica cómo solucionar el problema correctamente (la URL no parece relevante, pero lo prometo)

¿Por qué la diapositiva del teclado bloquea mi aplicación?

Usé un bloque try – catch para resolver el problema temporalmente.

 // Unregister Observer - Stop monitoring the underlying data source. if (mDataSetChangeObserver != null) { // Sometimes the Fragment onDestroy() unregisters the observer before calling below code // See http://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error try { getContext().unregisterReceiver(mDataSetChangeObserver); mDataSetChangeObserver = null; } catch (IllegalArgumentException e) { // Check wether we are in debug mode if (BuildConfig.IS_DEBUG_MODE) { e.printStackTrace(); } } } 

Declare el receptor como nulo y luego ponga los métodos de registro y anulación del registro en onResume () y onPause () de la actividad, respectivamente.

 @Override protected void onResume() { super.onResume(); if (receiver == null) { filter = new IntentFilter(ResponseReceiver.ACTION_RESP); filter.addCategory(Intent.CATEGORY_DEFAULT); receiver = new ResponseReceiver(); registerReceiver(receiver, filter); } } @Override protected void onPause() { super.onPause(); if (receiver != null) { unregisterReceiver(receiver); receiver = null; } } 

Cuando se destruye el componente UI que registra el BR, también lo es el BR. Por lo tanto, cuando el código llega a anular el registro, es posible que el BR ya haya sido destruido.

Para cualquiera que encuentre este problema y probaron todo lo que se sugirió y nada funciona, así es como LocalBroadcastManager.getInstance(this).registerReceiver(...) mi problema, en lugar de hacer LocalBroadcastManager.getInstance(this).registerReceiver(...) Primero creé una variable local de tipo LocalBroadcastManager,

 private LocalBroadcastManager lbman; 

Y usé esta variable para llevar a cabo el registro y anulación del registro en el receptor de difusión, es decir

 lbman.registerReceiver(bReceiver); 

y

 lbman.unregisterReceiver(bReceiver);