Android – La mejor manera de implementar LocationListener a través de múltiples actividades

He estado atrapado en este problema desde hace bastante tiempo. Estoy trabajando en una aplicación que utiliza la ubicación bastante ampliamente en varias actividades diferentes. Cada ejemplo que he encontrado utiliza un LocationListener separado en cada actividad. Esto no es factible en mi situación.

Me estoy preguntando cuál es la manera más eficiente de no perder de vista la localización del usuario a través de varias actividades. En este momento, he creado un servicio que implementa LocationListener y utiliza una difusión para actualizar lat y campos largos estáticos en una clase base de actividad. Esto significa que el servicio está siempre en ejecución, lo que no es ideal. Pero si cierro el servicio y lo reinicio sólo cuando lo necesito, se necesita tiempo para obtener una buena ubicación. Necesito los datos de ubicación en OnCreate de la actividad (). Es lo mismo si intento implementarlo en la clase base de la actividad. Si registro constantemente el oyente en onResume / onCreate y lo cancelo en onPause (), toma demasiado tiempo para comenzar a recibir actualizaciones. También traté de crear un servicio al que podría vincular, por lo que sólo se inicia cuando necesito una ubicación. Pero tengo el mismo problema, se tarda demasiado tiempo para enlazar con el servicio y empezar a obtener actualizaciones.

El servicio que estoy usando ahora funciona, pero de todo lo que he leído, no debería estar utilizando un servicio constantemente en ejecución para cosas triviales como este. Pero todo el punto de la aplicación es proporcionar datos relevantes basados ​​en la ubicación actual del usuario. Así que tengo un servicio que sólo se ejecuta en segundo plano y proporciona actualizaciones periódicamente. El único problema importante que me ha hecho reexaminar el diseño en este punto es que recientemente descubrí que onProviderEnabled () no se llama si el usuario inicia la aplicación sin GPS activado y luego lo habilita posteriormente. En este escenario, la aplicación no tiene forma de reconocer que el GPS estaba habilitado para que pueda empezar a escuchar las actualizaciones.

Pensé que entendí LocationManager y LocationListener de mirar los ejemplos pero no puedo parecelo aplicarlo a esta situación donde necesito datos de la localización en varias actividades. Cualquier ayuda o consejo sería muy apreciada.

La forma en que normalmente implementaría este requisito es usar una implementación de servicio enlazada, como la de la Muestra de servicio local en la documentación de SDK. Obviamente, está familiarizado con la ventaja del Servicio, lo que le permite crear todo el código de ubicación una sola vez.

El acceso al servicio a través de enlaces permite que el servicio se inicie y se detenga por sí mismo para que no se ejecute cuando su aplicación no está en primer plano (que morirá tan pronto como no más actividades están vinculados). La clave, IMO, es que BIND el servicio en onStart() y UNBIND en onStop() , porque estas dos llamadas se superponen al pasar de una actividad a otra (la segunda actividad comienza antes de que la primera deje de funcionar). Esto evita que el Servicio muera cuando se mueve dentro de la aplicación y sólo deja que el servicio muera cuando la aplicación completa (o al menos cualquier parte interesada en la ubicación) sale del primer plano.

Con Enlaces, no es necesario pasar los datos de Ubicación en una Transmisión, ya que la Actividad puede llamar a métodos directamente en el Servicio para obtener la ubicación más reciente. Sin embargo, una difusión todavía sería ventajosa como un método de indicar cuándo una nueva actualización está disponible … pero esto sólo se convertiría en un notificador de la actividad de escucha para llamar al método getLocation() en el servicio.

Mis $ 0.02. ¡Espero que ayude!

Tengo el mismo problema y traté de resolverlo con la buena respuesta de Devunwired, pero tuve algunos problemas. No pude encontrar una manera de detener el servicio y cuando terminé mi aplicación, el módulo GPS todavía estaba funcionando. Así que encontré otra manera:

Escribí una clase GPS.java:

 public class GPS { private IGPSActivity main; // Helper for GPS-Position private LocationListener mlocListener; private LocationManager mlocManager; private boolean isRunning; public GPS(IGPSActivity main) { this.main = main; // GPS Position mlocManager = (LocationManager) ((Activity) this.main).getSystemService(Context.LOCATION_SERVICE); mlocListener = new MyLocationListener(); mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); // GPS Position END this.isRunning = true; } public void stopGPS() { if(isRunning) { mlocManager.removeUpdates(mlocListener); this.isRunning = false; } } public void resumeGPS() { mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); this.isRunning = true; } public boolean isRunning() { return this.isRunning; } public class MyLocationListener implements LocationListener { private final String TAG = MyLocationListener.class.getSimpleName(); @Override public void onLocationChanged(Location loc) { GPS.this.main.locationChanged(loc.getLongitude(), loc.getLatitude()); } @Override public void onProviderDisabled(String provider) { GPS.this.main.displayGPSSettingsDialog(); } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } } } 

Esta clase se utiliza en cada Actividad que necesita las coordenadas GPS. Cada actividad tiene que implementar la siguiente interfaz (necesaria para la comunicación):

 public interface IGPSActivity { public void locationChanged(double longitude, double latitude); public void displayGPSSettingsDialog(); } 

Ahora mi actividad principal se ve así:

 public class MainActivity extends Activity implements IGPSActivity { private GPS gps; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); gps = new GPS(this); } @Override protected void onResume() { if(!gps.isRunning()) gps.resumeGPS(); super.onResume(); } @Override protected void onStop() { gps.stopGPS(); super.onStop(); } public void locationChanged(double longitude, double latitude) { Log.d(TAG, "Main-Longitude: " + longitude); Log.d(TAG, "Main-Latitude: " + latitude); } @Override public void displayGPSSettingsDialog() { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent); } } 

Y una segunda así:

 public class TEST4GPS extends Activity implements IGPSActivity{ private GPS gps; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.gps = new GPS(this); } @Override public void locationChanged(double longitude, double latitude) { Log.d("TEST", "Test-Longitude: " + longitude); Log.d("TEST", "Test-Latitude: " + latitude); } @Override protected void onResume() { if(!gps.isRunning()) gps.resumeGPS(); super. onResume(); } @Override protected void onStop() { gps.stopGPS(); super.onStop(); } @Override public void displayGPSSettingsDialog() { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent); } } 

No es tan hermosa como la solución de Devunwired, pero funciona para mí. Cya

Usted podría tener su servicio de escritura de su lat & long coords a un sqlite db en el cambio de esa manera usted no tiene el servicio vinculante gastos generales y sus coords será accesible a través de todas sus actividades.

Tal vez en su actividad principal puede comprobar el estado del GPS y si está apagado, puede solicitar al usuario que lo habilite. Una vez que el GPS está activado, inicie su servicio.

Aquí está una manera muy simple y directa de hacerlo:

En su actividad principal:

 private boolean mFinish; @Override public void onBackPressed() { mFinish = true; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mFinish = false; ... } @Override public void onPause(){ super.onPause(); if (mFinish) { // remove updates here mLocationManager.removeUpdates(mLocationListener); } } 

Esto sólo eliminará el oyente de actualizaciones si presiona Atrás en su actividad principal, pero de lo contrario permanezca activado.

No es la mejor manera de hacerlo, pero es una solución simple de copiar y pegar.

Asegúrese de no llamar a la persona que escucha la ubicación si ya se está ejecutando (por ejemplo en la pantalla girar), de lo contrario terminará con varios oyentes ejecutándose en segundo plano.

  • String 'xyz' marcada como intraducible pero que existe en la localidad 'ja'
  • Obtener la ubicación / posición más precisa? (GPS / Kalman / Android)
  • Forzar locale para Android con resConfig
  • ¿Cuál es la mejor práctica para externalizar la traducción de aplicaciones en Android?
  • Habilitar a terceros independientes para localizar aplicaciones de Android; Datos de localización fuera del APK de la aplicación
  • ¿Cómo se establece el lenguaje de etiquetas de mapa en Google Maps Android API v2
  • Localización de Android
  • ¿Puede la aplicación de Android tener un nombre diferente dependiendo del idioma / portador?
  • Cómo eliminar fácilmente los recursos de localización innecesarios de bibliotecas añadidas en la versión APK
  • Androide. ¿Cómo usar los mismos mensajes localizables para todos los idiomas de un país?
  • Después de la rotación de la pantalla, se cambiará el idioma de mi aplicación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.