2015-06-11 22 views
5

Oznacza to, że mam ten BroadcastReceiver, który tworzę w locie, aby odsłuchać jeden broadast, po czym chcę go wyrejestrować.Czy można wyrejestrować "dynamiczny" program BroadcastReceiver z własnej metody onReceive() odbiornika?

Nie znalazłem żadnego kodu przykładowego, który robi to w ten sposób, ale też nie znalazłem żadnej reguły w androidowych dokumentach online, które zabraniają tego. Ale nie mogę pozwolić, aby zwlekał tak długo, jak działanie, i to jest w anonimowej klasie tak, więc klasa zawierająca nawet nie zna nazwy zmiennej.

Oznacza to, że kod wygląda mniej więcej tak:

myInfoReceiver = new BroadcastReceiver() { 
onReceive(Context ctx, Intent intt) { 
    // do some Notification when I get here 
    nm.notify("I got here") // obvious pseudo code 
    ctx.unregisterReceiver(myInfoReceiver); 
} // end onReceive 
ctx.registerReceiver),uInfoReceiver, new IntentFilter(...)); 
}; // end BroadcastReceiver 

Ale gdy uruchamiam to, Android narzeka gdy wywołuje wyrejestrować, podkreślając, że odbiornik nie jest tam, aby wyrejestrować (nie pamiętam dokładnego brzmienia, ale wyrzucił wyjątek IllegalArgumentException).

Próbowałem także zmodyfikować kod, aby sprawdzić, czy akcja w "intt" jest taka sama, jak oczekiwano - ale potem nadal wykonuje test onReceive, ale po cichu się nie wyrejestruje.

+0

Co cel do ciebie chcesz osiągnąć? Przypuszczam, że 'BroadcastReceiver' może być złym wyborem dla twojego problemu. Jeśli chcesz wykonać operację raz i chcesz uniezależnić ją od cyklu życia aktywności, rozważ użycie 'IntentService' lub' Service' z szyną zdarzeń (np. Otto). –

+0

Nie użyłbym IntentService itp., Ponieważ większy system, który jest częścią już ma zamiar transmisji, reprezentujący dokładnie żądaną informację. Ponadto nie potrzebuję takiej niezależności od cyklu życia. Jestem już w wątku UI czekającym na ten zamiar, nic nie robiąc, ale pokazując okno postępu. –

Odpowiedz

5

Odpowiedź na twoje pytanie brzmi "tak". Jednak ...

... musisz zadzwonić pod numer unregisterReceiver() na tym samym Context, który nazywasz registerReceiver(). W opublikowanym przez ciebie kodzie wywołujesz unregisterReceiver() na Context przekazywany jako argument do onReceive(). To nie to samo Context, dlatego właśnie otrzymujesz wyjątek.

+0

Od pewnego czasu jestem podejrzany o kontekst. Dziękuję za pewność. –

+0

Mam teraz do czynienia z tym problemem. Czy jest dobra praca? – user2892437

0

Powiedziałbym po prostu TAK, bez problemu.

Używam go na przykład do jednorazowej naprawy lokacji i można z niego korzystać również w innych logikach, nie widząc w tym żadnego problemu.

Plus Widziałem to wiele razy.

+0

Też bym pomyślał "żaden problem". Ale dostaję wyjątek IllegalArgumentException. Każdy pomysł, dlaczego? W jaki sposób nie można go jeszcze zarejestrować we własnej metodzie onReceive()? –

+0

Czy mijasz prawidłowy obiekt odbiornika podczas wyrejestrowywania odbiornika, ponieważ mogłem zobaczyć niezgodność w powyższym kodzie opublikowanym – 7383

+0

Po prostu musisz wywołać to na tym samym "Kontekście". Użyj np. 'MyActivity.this' dla' Activity' na przykład. W przeciwnym razie, proszę wysłać stos stacktrace. – shkschneider

0

Próbowałem różnych rozwiązań, w końcu robię to w ten sposób:

Rejestrowanie:

MyApplication.getInstance().getApplicationContext().registerReceiver(sentReceiver, new IntentFilter(SENT)); 

SentReceiver:

public class SentReceiver extends BroadcastReceiver { 
    public void onReceive(Context context, Intent arg1) { 
     switch (getResultCode()) { 
      case Activity.RESULT_OK: 
       Toast.makeText(context, 
         context.getString(R.string.sms_envoye), Toast.LENGTH_SHORT) 
         .show(); 
       break; 
      case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
       Toast.makeText(context, 
         context.getString(R.string.sms_defaillance_generique), 
         Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NO_SERVICE: 
       Toast.makeText(context, 
         context.getString(R.string.sms_pas_de_service), 
         Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_NULL_PDU: 
       Toast.makeText(context, 
         context.getString(R.string.sms_pas_de_pdu), 
         Toast.LENGTH_SHORT).show(); 
       break; 
      case SmsManager.RESULT_ERROR_RADIO_OFF: 
       Toast.makeText(context, 
         context.getString(R.string.sms_radio_desactivee), 
         Toast.LENGTH_SHORT).show(); 
       break; 
     } 
     MyApplication.getInstance().getApplicationContext().unregisterReceiver(this); 
    } 

Z MyApplication:

public class MyApplication extends Application { 
    private static MyApplication mInstance; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mInstance = this; 
    } 

    public static synchronized MyApplication getInstance() { 
     return mInstance; 
    }   
}