Odbiornik niezarejestrowany błąd wyjątku?

W mojej konsoli programistów ludzie zgłaszają błąd, którego nie mogę odtworzyć na żadnym posiadanym telefonie. Jedna osoba zostawiła wiadomość, że dostaje ją, gdy próbuje otworzyć ekran ustawień mojej usługi baterii. Jak widać po błędzie mówi, że odbiornik nie jest zarejestrowany.

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)

I register is in my 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);
}

Unregister in onDestroy and also with a preference listener

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

}

A to mój odbiornik w służbie

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

Any dlaczego mieliby dostać ten błąd?

Author: tyczj, 2011-05-29

9 answers

Źródło problemu znajduje się tutaj:

 unregisterReceiver(batteryNotifyReceiver);

Jeśli odbiornik był już niezarejestrowany (prawdopodobnie w kodzie, którego nie podałeś w tym poście) lub nie był zarejestrowany, to zadzwoń do unregisterReceiver throws IllegalArgumentException. W Twoim przypadku musisz po prostu umieścić specjalny try / catch dla tego wyjątku i zignorować go (zakładając, że nie możesz lub nie chcesz kontrolować liczby razy, które wywołujesz unregisterReceiver na tym samym recevierze).

 186
Author: inazaruk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-29 00:59:38

Użyj tego kodu wszędzie dla niezarejestrowanego:

if (batteryNotifyReceiver!=null) {
    unregisterReceiver(batteryNotifyReceiver);
    batteryNotifyReceiver=null;
}
 19
Author: xnagyg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 22:15:00

Bądź ostrożny, gdy zarejestrujesz się przez

LocalBroadcastManager.getInstance(this).registerReceiver()

Nie możesz wyrejestrować się przez

 unregisterReceiver()

Musisz użyć

LocalBroadcastManager.getInstance(this).unregisterReceiver()

Lub aplikacja ulegnie awarii, Zaloguj się w następujący sposób:

09-30 14:00:55.458 19064-19064/com.jialan.guangdian.zobacz E / AndroidRuntime: FATAL wyjątek: main Proces: kom.jialan.guangdian.widok, pid: 19064 java.lang.RuntimeException: nie można zatrzymać usługi com.google.android.egzoplayer.demo.gracz.PlayService@141ba331: java.lang.IllegalArgumentException: odbiorca niezarejestrowany: com.google.android.egzoplayer.demo.gracz.PlayService$PlayStatusReceiver@19538584 w android.app./ Align = "left" / handleStopService (właśc.wyswietlen: 2941) na android.app./ Align = "left" / dostęp $ 2200 (ActivityThread.Java:148) w android.app.ActivityThread$H. handleMessage (ActivityThread.wyswietlen: 1395) w android.os.Handler.dispatchMessage (Handler.Java:102) w android.os.Looper.Pętla (Looper.Java:135) w android.app./ Align = "left" / główna(Biał.wyswietlen: 5310) na Javie.lang.zastanów się.Metoda.invoke(metoda natywna) na Javie.lang.zastanów się.Metoda.invoke (metodaJava:372) na com.android.wewnętrzne.os.ZygoteInit$MethodAndArgsCaller.bieg (ZygoteInit.Java:901) na kom.android.wewnętrzne.os.ZygoteInit.główna (ZygoteInit.wyswietlen: 696) Spowodowane przez: java.lang.IllegalArgumentException: odbiorca niezarejestrowany: com.google.android.egzoplayer.demo.gracz.PlayService$PlayStatusReceiver@19538584 w android.app.LoadedApk.forgetReceiverDispatcher (LoadedApk.wyswietlen: 769) w android.app.ContextImpl.unerwisterreceiver (ContextImpl.wyswietlen: 1794) w android.treść.ContextWrapper.unerwisterreceiver (ContextWrapper.Java: 510) na kom.google.android.egzoplayer.demo.gracz.PlayService.onDestroy (PlayService.Java:542) w android.app./ Align = "left" / handleStopService (właśc.wyswietlen: 2924) w android.app./ Align = "left" / dostęp $ 2200 (ActivityThread.Java:148)  na android.app.ActivityThread$H. handleMessage (ActivityThread.wyswietlen: 1395)  w android.os.Handler.dispatchMessage (Handler.Java:102)  w android.os.Looper.Pętla (Looper.Java:135)  w android.app./ Align = "left" / główna(Biał.wyswietlen: 5310)  na Javie.lang.zastanów się.Metoda.invoke(metoda natywna)  na Javie.lang.zastanów się.Metoda.invoke (metodaJava:372)  na kom.android.wewnętrzne.os.ZygoteInit$MethodAndArgsCaller.bieg (ZygoteInit.Java:901)  na com.android.wewnętrzne.os.ZygoteInit.główna (ZygoteInit.java:696)

 15
Author: Chuanhang.gu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-30 09:36:26

Jak wspomniano w innych odpowiedziach, wyjątek jest wyrzucany, ponieważ każde wywołanie do {[1] } nie jest dopasowane dokładnie do jednego wywołania do unregisterReceiver. Dlaczego nie?

An Activity nie zawsze ma pasujące onDestroy Wywołanie dla każdego onCreate. Jeśli w systemie zabraknie pamięci, Twoja aplikacja zostanie eksmitowana bez wywołania onDestroy.

Właściwe miejsce do umieszczenia registerReceiver jest w wywołaniu onResume, a unregisterReceiver w onPause. Ta para połączeń jest zawsze dopasowana. Więcej informacji znajduje się w diagramie cyklu aktywności szczegóły. http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

Twój kod zmieni się na:

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
Author: Curmudgeonlybumbly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 20:19:33

EDIT: to jest odpowiedź dla inazaruk i electrichead... Natknąłem się na podobny problem do nich i dowiedziałem się, co następuje...

Istnieje od dawna błąd dla tego problemu tutaj: http://code.google.com/p/android/issues/detail?id=6191

Wygląda na to, że zaczęło się wokół Androida 2.1 i było obecne we wszystkich androidach 2.x wypuszcza od tego czasu. Nie jestem pewien, czy nadal jest to problem w Androidzie 3.x lub 4.X.

W każdym razie, ten post StackOverflow wyjaśnia jak poprawnie obejść problem (nie wygląda to na istotne przez URL, ale obiecuję, że tak jest)

Dlaczego Keyboard-slide powoduje awarię mojej aplikacji?

 11
Author: Justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:46

Użyłem bloku try - catch, aby tymczasowo rozwiązać problem.

// 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
Author: Rowland Mtetezi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-22 21:10:16

Zadeklaruj odbiornik jako null, a następnie umieść metody register i unregister odpowiednio w onresume () i onPause() aktywności.

@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
Author: Sagar D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-27 22:13:24

Gdy komponent UI, który rejestruje BR, jest zniszczony, tak jest BR. W związku z tym, gdy kod dotrze do niezarejestrowania, BR może już zostać zniszczony.

 0
Author: ousanmaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-26 04:19:45

Dla każdego, kto natknie się na ten problem i spróbuje wszystkiego, co zostało zasugerowane i nic nadal nie działa, oto jak rozwiązałem swój problem, zamiast robić LocalBroadcastManager.getInstance(this).registerReceiver(...) Po raz pierwszy utworzyłem zmienną lokalną typu LocalBroadcastManager,

private LocalBroadcastManager lbman;

I użył tej zmiennej do przeprowadzenia rejestracji i wyrejestrowania na broadcastreceiver, czyli

lbman.registerReceiver(bReceiver);

I

lbman.unregisterReceiver(bReceiver);
 0
Author: nada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-14 11:16:30