Dans ma console développeur, les gens continuent de signaler une erreur que je ne peux reproduire sur aucun de mes téléphones. Une personne a laissé un message disant qu'elle l'obtient lorsqu'elle essaie d'ouvrir l'écran des paramètres de mon service de batterie. Comme vous pouvez le voir dans l'erreur, il est indiqué que le récepteur n'est pas enregistré.
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)
Je m'inscris est dans mon 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);
}
Se désinscrire dans onDestroy et aussi avec un écouteur de préférences
@Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(batteryNotifyReceiver);
}
et c'est mon récepteur dans le service
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 < lastLevel){
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);
}
}
une idée pourquoi ils obtiendraient cette erreur?
LocalBroadcastManager.getInstance(context).unregisterReceiver()
oucontext.unregisterReceiver()
Soyez prudent, lorsque vous vous inscrivez par
vous ne pouvez pas vous désinscrire par
Tu dois utiliser
ou l'application plantera, connectez-vous comme suit:
la source
Utilisez ce code partout pour unregisterReceiver:
la source
Comme mentionné dans d'autres réponses, l'exception est levée car chaque appel à
registerReceiver
ne correspond pas exactement à un appel àunregisterReceiver
. Pourquoi pas?An
Activity
n'a pas toujours unonDestroy
appel correspondant pour chaqueonCreate
appel. Si le système manque de mémoire, votre application est expulsée sans appeleronDestroy
.Le bon endroit pour passer un
registerReceiver
appel est dans l'onResume
appel etunregisterReceiver
dansonPause
. Cette paire d'appels est toujours mise en correspondance. Consultez le diagramme du cycle de vie des activités pour plus de détails. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycleVotre code deviendrait:
la source
EDIT: C'est la réponse pour inazaruk et electrichead ... J'avais rencontré un problème similaire à eux et j'ai découvert ce qui suit ...
Il existe un bogue de longue date pour ce problème ici: http://code.google.com/p/android/issues/detail?id=6191
On dirait qu'il a commencé autour d'Android 2.1 et est présent dans toutes les versions d'Android 2.x depuis. Je ne sais pas si c'est toujours un problème sous Android 3.x ou 4.x.
Quoi qu'il en soit, cet article de StackOverflow explique comment contourner le problème correctement (cela ne semble pas pertinent par l'URL mais je le promets)
Pourquoi le clavier-slide plante-t-il mon application?
la source
J'ai utilisé un bloc try - catch pour résoudre temporairement le problème.
la source
Déclarez le receveur comme nul, puis placez les méthodes register et unregister respectivement dans onResume () et onPause () de l'activité.
la source
Lorsque le composant UI qui enregistre le BR est détruit, le BR l'est aussi. Par conséquent, lorsque le code arrive à la désinscription, le BR peut avoir déjà été détruit.
la source
Pour tous ceux qui rencontreront ce problème et qui ont essayé tout ce qui a été suggéré et que rien ne fonctionne toujours, c'est ainsi que j'ai trié mon problème, au lieu de le faire,
LocalBroadcastManager.getInstance(this).registerReceiver(...)
j'ai d'abord créé une variable locale de type LocalBroadcastManager,Et utilisé cette variable pour effectuer l'enregistrement et le désenregistrement sur le récepteur de diffusion, c'est-à-dire
et
la source
Supposons que votre
broadcastReceiver
soit défini comme ceci:Si vous utilisez
LocalBroadcast
dans une activité, voici comment vous désinscrire:Si vous utilisez
LocalBroadcast
dans un Fragment, voici comment vous désinscrire:Si vous utilisez la diffusion normale dans une activité, voici comment vous désinscrire:
Si vous utilisez la diffusion normale dans un fragment, voici comment vous désinscrire:
la source