2011-02-10 17 views
21

Tengo un BroadcastReceiver para un uso único.Anular el registro del receptor de difusión de Android en onReceive lanza "Receptor no registrado"

Lo estoy registrando en una Actividad. No puedo poner el unregisterReceiver() en porque tiene que seguir funcionando incluso cuando la actividad está en pausa o destruida.

Quiero que el BroadcastReceiver para anular el registro en sí cuando se hace, algo como esto:

public class SmsReceiver extends BroadcastReceiver { 

    public void onReceive(Context context, Intent intent) { 
      // do some code.. 
      context.unregisterReceiver(this) 
     } 
} 

pero causa una excepción: Receiver not registered.

Respuesta

24

A BroadcastReceiver solo existe durante la ejecución de su método onReceive(). Por lo tanto, este se evalúa como una instancia desechable cada vez que se inicia/recibe la transmisión. Ver Broadcast Receiver Lifecycle. Para registrar/anular el registro dinámicamente de BroadcastReceiver s, debe recordar la instancia de su receptor en onPause() para registrarlo de nuevo durante onResume().

+0

Un objeto BroadcastReceiver sigue las mismas reglas de recolección de basura que cualquier otro objeto. No hay una "instancia desechable" especial. Hacer referencia a 'this' en' onReceive' da el mismo resultado que una referencia desde cuando se creó el objeto (pruébelo). La documentación habla de que se ha matado al * proceso * del receptor, no a nada en el nivel del objeto receptor. – blahdiblah

0

Ha intentado anular el registro del reciver de un servicio/actividad? Tal vez haya algún problema si lo llamas desde el receptor para anular el registro.

0

Probablemente ya lo haya desregistrado en otro lugar de su programa, por improbable que esto pueda sonar. Tal vez en algún lugar antes de su context.unregisterReceiver, pero en el método onReceive invoca una acción, que da como resultado la anulación de la regenta del receptor antes de llegar al context.unregisterReceiver.

Solo asegúrese de anular el registro en el menor número posible de lugares, preferiblemente, exactamente uno.

+2

Pero si yo no registrado ya, ¿cómo es que todavía se pone a ese punto y ejecuta el método de cancelar el registro? No es posible ... – shaimagz

0

Tal vez el problema es que está tratando de anular el registro del receptor del contexto del del receptor, en lugar del contexto donde se registró originalmente.

3

Simplemente agregue una llamada de método a la Actividad en la que lo registró, y en ese método, anule el registro del receptor. De esa manera usted sabe su trabajo ha sido hecho.

Sin embargo, el receptor no funcionará si la actividad se detiene o destruye de todos modos. Tendría que declararlo en el manifiesto o bien registrarlo en un servicio de larga ejecución para mantenerlo funcionando fuera de la vida de una actividad. Por lo que yo sé, no puede anular el registro de un receptor declarado en el manifiesto porque no obtiene la instancia con la que está registrado. Pero la llamada de método al Servicio para anular el registro debería funcionar.

Si solo necesita un trabajador para un solo uso, declare un IntentService exportado en el manifiesto con la acción que está transmitiendo. Ese IntentService se iniciará cuando se reciba el intento y se le dé el intento que lo inició, y luego cuando haya terminado su tarea, se detendrá por sí mismo.

10

Sé que esta pregunta ya tiene una respuesta, pero probar este Código

Este código es para BatteryInfo. Y funcionó.

private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context arg0, Intent intent) { 
     // TODO Auto-generated method stub 
     int level = intent.getIntExtra("level", 0); 
     Log.i("Battery", String.valueOf(level) + "%"); 
     arg0.unregisterReceiver(mBatInfoReceiver); 
    } 

}; 

//Below code is the Code which attaches the reciever put this code in which ever place you want. 

this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(
       Intent.ACTION_BATTERY_CHANGED)); 

de referencia para la fijación de StackOverFlow/Tutorial

+0

esto no funcionó para mí, dice que no está registrado. creo que el mBatInfoReceiver original no existe cuando se llama onReceive – hyena

2

he encontrado con el mismo problema, en realidad, la respuesta correcta es LocalBroadcastManager.getInstance(context).unregisterReceiver(this); pero no context.unregisterReceiver(this)

+0

¿Echas de menos algo en tu respuesta? "pero no 'ingrese el código aquí'". Por favor, corrige –

+0

Eso no funcionó para mí, he publicado otra solución [aquí] (http://stackoverflow.com/a/39748974/4221945) –

Cuestiones relacionadas