Récepteur non enregistré erreur d'exception?

dans ma console de développeur, les gens continuent de signaler une erreur que je ne peux reproduire sur Aucun téléphone que j'ai. Une personne a laissé un message disant qu'il obtient quand ils essaient d'ouvrir l'écran des paramètres de la batterie de mon service. Comme vous pouvez le voir à partir de l'erreur, il dit 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.access00(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 le registre 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);
}

annuler l'inscription dans onDestroy et aussi avec une préférence listener

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

}

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

vous savez pourquoi ils ont eu cette erreur?

94
demandé sur tyczj 2011-05-29 03:46:11

9 réponses

la racine de votre problème se trouve ici:

 unregisterReceiver(batteryNotifyReceiver);

si le destinataire n'était pas déjà enregistré (probablement dans le code que vous n'avez pas inclus dans ce message) ou n'était pas enregistré, alors appeler unregisterReceiver lance IllegalArgumentException . Dans votre cas, vous avez juste besoin de mettre spécial essayer / attraper pour cette exception et l'ignorer (en supposant que vous ne pouvez pas ou ne voulez pas contrôler le nombre de fois où vous appelez unregisterReceiver sur le même receveur).

186
répondu inazaruk 2011-05-29 00:59:38

utilisez ce code partout pour non-livraison:

if (batteryNotifyReceiver!=null) {
    unregisterReceiver(batteryNotifyReceiver);
    batteryNotifyReceiver=null;
}
19
répondu xnagyg 2015-01-13 22:15:00

attention, quand vous vous enregistrez par

LocalBroadcastManager.getInstance(this).registerReceiver()

vous ne pouvez pas annuler l'enregistrement par

 unregisterReceiver()

vous devez utiliser

LocalBroadcastManager.getInstance(this).unregisterReceiver()

ou app crash, se connecter comme suit:

09-30 14:00:55.458 19064-19064/com.jialan.guangdian.vue E/AndroidRuntime: FATAL EXCEPTION: main Processus: com.jialan.guangdian.vue, PID: 19064 Java.lang.RuntimeException: impossible d'arrêter le service com.Google.Android.exoplayer.démo.joueur.PlayService@141ba331: java.lang.IllegalArgumentException: récepteur non enregistré: com.Google.Android.exoplayer.démo.joueur.PlayService$PlayStatusReceiver@19538584 à Android.App.ActivityThread.handleStopService (ActivityThread.java: 2941) au android.App.ActivityThread.accès 2200$(ActivityThread.java: 148) au android.App.ActivityThread$H. handleMessage (ActivityThread.java: 1395) à Android.OS.Manipulateur.dispatchMessage (Handler.java: 102) au android.OS.Looper.boucle (Looper.java: 135) au android.App.ActivityThread.main (ActivityThread.java: 5310) à java.lang.refléter.Méthode.invoke (méthode Native)) à java.lang.refléter.Méthode.invoke(la Méthode.java: 372) au com.Android.interne.OS.ZygoteInit $ MethodAndArgsCaller.exécuter(ZygoteInit.java: 901) au com.Android.interne.OS.ZygoteInit.main(ZygoteInit.java: 696) Causées par: Java.lang.IllegalArgumentException: récepteur non enregistré: com.Google.Android.exoplayer.démo.joueur.PlayService$PlayStatusReceiver@19538584 au android.App.LoadedApk.forget receiverdispatcher (LoadedApk.java: 769) au android.App.ContextImpl.unmisterreceiver (ContextImpl.java: 1794) au android.contenu.ContextWrapper.unmisterreceiver (ContextWrapper.java: 510) au com.Google.Android.exoplayer.démo.joueur.PlayService.onDestroy (PlayService.java: 542) au android.App.ActivityThread.handleStopService (ActivityThread.java: 2924) au android.App.ActivityThread.accès 2200$(ActivityThread.java: 148)  au android.App.ActivityThread$H. handleMessage (ActivityThread.java: 1395)  au android.OS.Manipulateur.dispatchMessage (Handler.java: 102)  au android.OS.Looper.boucle (Looper.java: 135)  au android.App.ActivityThread.main (ActivityThread.java: 5310)  à java.lang.refléter.Méthode.invoke (méthode Native))  à java.lang.refléter.Méthode.invoke(la Méthode.java: 372)  à COM.Android.interne.OS.ZygoteInit $ MethodAndArgsCaller.exécuter(ZygoteInit.java: 901)  au com.Android.interne.OS.ZygoteInit.main(ZygoteInit.java: 696)

15
répondu Chuanhang.gu 2016-09-30 09:36:26

comme mentionné dans d'autres réponses, l'exception est lancée parce que chaque appel à registerReceiver ne correspond pas exactement à un appel à unregisterReceiver . Pourquoi pas?

Un Activity n'a pas toujours une correspondance onDestroy appel à tous onCreate appel. Si le système manque de mémoire, votre application est expulsé sans appel onDestroy .

l'endroit approprié pour placer un appel registerReceiver est dans l'appel onResume , et unregisterReceiver dans onPause . Cette paire d'appels est toujours accompagnée. Voir le diagramme du cycle de vie des activités pour plus de détails. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

votre code changerait en:

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);
}
13
répondu Curmudgeonlybumbly 2015-02-12 20:19:33

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 y a un bug de longue date pour ce problème ici: http://code.google.com/p/android/issues/detail?id=6191

semble comme il a commencé autour D'Android 2.1 et a été présent dans tous les Android 2.X sort depuis. Je ne suis pas sûr que ce soit toujours un problème sur Android 3.x ou 4.x bien.

quoi qu'il en soit, ce post StackOverflow explique comment contourner le problème correctement (il ne semble pas pertinent par L'URL mais je vous promets qu'il est)

pourquoi le clavier-diapo bloque mon application?

11
répondu Justin 2017-05-23 12:02:46

j'ai utilisé un bloc d'essai pour résoudre le problème temporairement.

// Unregister Observer - Stop monitoring the underlying data source.
        if (mDataSetChangeObserver != null) {
            // Sometimes the Fragment onDestroy() unregisters the observer before calling below code
            // See <a>http://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error</a>
            try  {
                getContext().unregisterReceiver(mDataSetChangeObserver);
                mDataSetChangeObserver = null;
            }
            catch (IllegalArgumentException e) {
                // Check wether we are in debug mode
                if (BuildConfig.IS_DEBUG_MODE) {
                    e.printStackTrace();
                }
            }
        }
6
répondu Rowland Mtetezi 2015-12-22 21:10:16

déclare le récepteur nul et met les méthodes de registre et de non-enregistrement dans onResume() et onPause() de l'activité respectivement.

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



        }
3
répondu Sagar D 2014-07-27 22:13:24

lorsque la composante D'assurance-chômage qui enregistre le re est détruite, il en est de même pour le re. Par conséquent, lorsque le code arrive à se désinscrire, le BR peut avoir déjà été détruit.

0
répondu ousanmaz 2016-09-26 04:19:45

pour tous ceux qui vont venir sur ce problème et ils ont essayé tout ce qui a été suggéré et rien ne fonctionne encore, c'est comment j'ai réglé mon problème, au lieu de faire LocalBroadcastManager.getInstance(this).registerReceiver(...) J'ai d'abord créé une variable locale de type LocalBroadcastManager,

private LocalBroadcastManager lbman;

et utilisé cette variable pour effectuer l'enregistrement et le désenregistrement sur le broadcastreceiver, c'est-à-dire

lbman.registerReceiver(bReceiver);

et

lbman.unregisterReceiver(bReceiver);
0
répondu nada 2017-07-14 11:16:30