tutorial start sendbroadcast registerreceiver oreo example connectivity_change android broadcastreceiver

android - start - Excepción extraña "Receptor no registrado"



start broadcast receiver android (5)

En onResume () hago:

registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));

y en onPause ():

unregisterReceiver(timeTickReceiver);

Veo los informes "java.lang.IllegalArgumentException: Receiver no registrado" en la Consola de desarrollador de Android (solo hay 2 informes y mi aplicación tiene miles de usuarios). La excepción es activada por unregisterReceiver (). ¿Qué puede estar pasando? No me siento muy seguro de rodearlo con try-catch.


Hemos visto este error al hacer una pulsación larga en una pantalla en particular, y luego realizar dos cambios de orientación (por ejemplo, voltear el dispositivo al revés).

La documentación API para unregisterReceiver dice:

Anular el registro de un BroadcastReceiver previamente registrado.

No lo dice explícitamente, pero como ha visto, IllegalArgumentException: Receiver not registered si aún no está registrado.

La solución que estoy usando es almacenar mi Receiver como un campo miembro, y tenerlo configurado como nulo cuando no está registrado, es decir, lo inicializo como nulo, y luego lo configuro solo cuando lo registro. ¡Esto podría no ser perfecto, pero soluciona mis choques!

private Receiver mReceiver = null;

Desde mi onServiceConnected:

sLog.debug("Registering receiver"); mReceiver = new Receiver(); registerReceiver(mReceiver, filter);

Desde mi onServiceDisconnected:

if (mReceiver == null) { sLog.info("Do not unregister receiver as it was never registered"); } else { sLog.debug("Unregister receiver"); unregisterReceiver(mReceiver); mReceiver = null; }


La opción más fácil sería envolver el bloque try / catch alrededor del código.

try{ ... this.unregisterReceiver(reciever); } catch(IllegalArgumentException e) { // TODO: handle exception } catch (Exception e) { // TODO: handle exception }


Supongo que puede haber algunos estados donde el receptor no está realmente registrado antes, por ejemplo, un usuario sale de la aplicación.

Es posible que desee intentar agregar un cheque para el receptor antes de ejecutar anular el registro, (lo he hecho en varios casos):

protected void onPause() { if(timeTickReceiver != null) { unregisterReceiver(timeTickReceiver); } }


Un BroadcastReceiver debe registrarse en el método del ciclo de vida de onCreate() :

private BroadcastReceiver receiver; @Overrride public void onCreate(Bundle savedInstanceState){ IntentFilter filter = new IntentFilter(); receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ... } } registerReceiver(receiver, filter); }

Y un BroadcastReceiver debe desregistrar en el método de ciclo de vida onDestory() :

@Override protected void onDestroy() { unregisterReceiver(receiver); }

Esto evitará el escenario de anular el registro de BroadcastReceiver que aún no se ha registrado.


Un receptor de difusión debe anular el registro en el método de ciclo de vida onPause()

protected void onPause() { this.unregisterReceiver(reciever); super.onPause(); }