Java.lang.IllegalArgumentException: Receptor no registrado

Tengo TrackingService componente para rastrear la ubicación de los autobuses en mi ciudad basada en Crowdsourcing. El TrackingService está operando en segundo plano, luego los datos se transmiten al servidor. Tengo una actividad de mapa para mostrar la ubicación de los buses, el usuario seleccionado en MainActivity (como filtro).

El fondo TrackingService se inicia en MainActivity cuando se inicia la aplicación.

I notificación de la actividad de map sobre la actualización lcoation con la ayuda de la BroadcastReceiver como en el código de abajo. Los datos se recuperan en la actividad del mapa, pero me encuentro con problemas para bReceiver registro de mi bReceiver . Quiero anular el registro de la transmisión cuando la aplicación va en segundo plano o cuando el usuario presiona el botón de nuevo, pero estoy recibiendo el error a continuación:

¿Cómo puedo arreglarlo?

Error:

 08-27 22:43:04.594: E/AndroidRuntime(19588): FATAL EXCEPTION: main 08-27 22:43:04.594: E/AndroidRuntime(19588): Process: com.bustracker, PID: 19588 08-27 22:43:04.594: E/AndroidRuntime(19588): java.lang.RuntimeException: Unable to stop activity {com.bustracker/com.bustracker.Map}: java.lang.IllegalArgumentException: Receiver not registered: com.bustracker.Map$1@2483d256 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4156) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4219) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.access$1500(ActivityThread.java:177) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1502) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.os.Handler.dispatchMessage(Handler.java:102) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.os.Looper.loop(Looper.java:145) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.main(ActivityThread.java:5944) 08-27 22:43:04.594: E/AndroidRuntime(19588): at java.lang.reflect.Method.invoke(Native Method) 08-27 22:43:04.594: E/AndroidRuntime(19588): at java.lang.reflect.Method.invoke(Method.java:372) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184) 08-27 22:43:04.594: E/AndroidRuntime(19588): Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.bustracker.Map$1@2483d256 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:822) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:2038) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:528) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.bustracker.Map.onStop(Map.java:418) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1275) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.Activity.performStop(Activity.java:6493) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4151) 08-27 22:43:04.594: E/AndroidRuntime(19588): ... 10 more 

Clase TrackingService:

 public class TrackingService extends Service implements LocationListener { public double pLong; public double pLat; ... @Override public int onStartCommand(Intent intent, int flags, int startId) { detectLocation(); return START_STICKY; } private void detectLocation() { lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0, this); } @Override public void onLocationChanged(Location location) { if (location != null) { pLong = location.getLongitude(); pLat = location.getLatitude(); Intent intent = new Intent(Map.RECEIVE_latLng); intent.putExtra("location",location); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); ..... } } 

Actividad del mapa:

  public class Map extends FragmentActivity implements OnMapReadyCallback { public static final String RECEIVE_latLng = "com.bustracker.RECEIVE_latLng"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(this); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(RECEIVE_latLng); bManager.registerReceiver(bReceiver, intentFilter); } private BroadcastReceiver bReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(RECEIVE_latLng)) { Location location = intent.getParcelableExtra("location"); double lng = location.getLongitude(); double lat = location.getLatitude(); LatLng ll = new LatLng(lat, lng); MarkerOptions markerOpt = new MarkerOptions().title("My Location") .position(ll); System.out.println("ABC map: "+ lat + " ; " + lng); myLocatMarker = map.addMarker(markerOpt); } } }; } @Override protected void onStop() { super.onStop(); unregisterReceiver(bReceiver); } 

Si se registra en onCreate() , tiene que anular su registro en onDestroy() . Si quieres anular el registro en onStop() debes registrarte en onStart() .

Echa un vistazo al ciclo de vida de la actividad aquí http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

La razón de esto es que onStop() se llama cuando la Activity pasa al fondo, pero no necesariamente se destruye. Cuando la Activity vuelve al primer plano onStart() se llama, pero no onCreate() para que BroadcastReceiver no se vuelva a registrar. Luego, cuando la Activity vuelve al fondo, onStop() trata de anular el registro de nuevo, pero el receptor no se ha registrado.

También necesita usar el LocalBroadcastManager para anular el registro de su receptor si lo usó para registrarlo de la siguiente manera:

 LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver); 

LocalBroadcastManager es una clase de la biblioteca de soporte :

Ayuda para registrar y enviar transmisiones de Intents a objetos locales dentro de su proceso.

Esto es diferente de los mismos métodos en Context que permiten difusiones en todo el sistema.

También vea una pregunta / respuesta similar aquí .

(Por supuesto, si lo desea) Puede registrar o onStop() registro en onStop() y onResume() simplemente envolverlo con try-catch:

try{ getActivity().registerReceiver(receiver,filter); } catch (Exception e){ // already registered } try{ getActivity().registerReceiver(receiver,filter); } catch (Exception e){ // already registered } Or

try{ getActivity().unregisterReceiver(receiver); } catch (Exception e){ // already unregistered }

Tenga en cuenta que debe registrarse y anular el registro en el mismo contexto. Por ejemplo, no se registra con el contexto de la aplicación y no se registra w / el contexto de la actividad.

No lo hagas

 getApplicationContext().registerReceiver(myReceiver, myIntentFilter); unregisterReceiver(myReceiver); 

Hacer esto en su lugar (dentro de una actividad)

 registerReceiver(myReceiver, myIntentFilter); unregisterReceiver(myReceiver); 

Normalmente me registro dentro de onPostResume() o onResume() y onPause() registro en onPause() después de la llamada super.onPause() .

Ejemplos:

 protected void onPostResume() { super.onPostResume(); registerReceiver(myReceiver, myIntentFilter); } 

 protected void onPause() { unregisterReceiver(tripInCartReceiver1); //called after unregistering super.onPause(); } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.