Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Android encuentra la ubicación GPS una vez, muestra el diálogo de carga

Estoy escribiendo una aplicación que requiere la ubicación actual del usuario (lastknownlocation no será muy útil) y muestra una lista de todos los "ítems" más cercanos a ellos tomados de la base de datos.

Tengo el hallazgo de los artículos más cercanos funcionando bien, pero sólo usando una latitud codificada y la ubicación de longitud por el momento, pero ahora es el momento de implementar la búsqueda de la ubicación real.

¿Puede alguien proporcionar un ejemplo de cómo hacer que la aplicación encuentre la ubicación correcta actual en segundo plano y que la aplicación espere. Sólo necesito la ubicación una vez no actualizaciones como la persona se mueve. He implementado un oyente de la localización sin embargo comprendo conseguir un arreglo del GPS puede ser lento. He visto otros ejemplos utilizando la última ubicación conocida o la implementación del oyente de ubicación que continúa ejecutándose y actualizando sin embargo como mi actividad necesita las coordenadas de ubicación antes de que pueda mostrar nada de la aplicación sólo se bloquea. Necesito mostrar un diálogo de progreso mientras que su búsqueda.

¿Cómo puedo hacer que el localizador de ubicación se ejecute una vez en segundo plano y, a continuación, eliminar las actualizaciones de ubicación una vez que encuentre la ubicación. Necesito el resto de la aplicación para esperar hasta que tenga una ubicación GPS o tiempo de espera después de decir 20-30segundos. Me gustaría un ProgressDialog para que el usuario sabe que algo está pasando, pero sólo tiene que ser la animación de hilado de carga no un porcentaje o nada. Si es posible, quisiera que el usuario pudiera cancelar el diálogo si están hartos de esperar que entonces pueden buscar mecanografiando el suburbio etc en lugar de otro.

He estado tratando de hacerlo con hilos, pero es cada vez más complicado de lo que siento que debería ser y aún no funciona de todos modos. En iPhone esto es mucho más simple?

¿Puede alguien proporcionar una buena manera de hacer esto, he estado arrancando mi cabello durante una semana en esto y es realmente ponerme atrasado para el resto de la fecha de finalización de la aplicación.

En resumen quiero:
* Buscar coordenadas actuales
* Mostrar diálogo de progreso mientras obtenga la ubicación
* ¿Tiene la aplicación ser capaz de esperar a la ubicación exitosa o renunciar después de un tiempo determinado?
* Si tiene éxito: Descartar diálogo de progreso y utilizar coordenadas para ejecutar mis otros métodos para encontrar elementos cerca.
* Si no se pudo obtener la ubicación: Descartar diálogo de progreso y mostrar mensaje de error, y alentar al usuario a utilizar el menú para ir a la actividad de búsqueda.
* Utilice estas coordenadas si el usuario elige la vista del mapa desde el menú, para mostrar la ubicación actual en el mapa y los alfileres se cayeron en todos los elementos cercanos mediante el uso de sus coordenadas de la base de datos.

Gracias chicos, espero haberme explicado lo suficiente. Cualquier pregunta apenas pide, estaré comprobando detrás regularmente mientras que soy afilado para conseguir esta pieza terminada. Aclamaciones

EDITAR
Código solicitado

Archivo de actividad locationList

protected void onStart() { super.onStart(); // .... new LocationControl().execute(this); } private class LocationControl extends AsyncTask<Context, Void, Void> { private final ProgressDialog dialog = new ProgressDialog(branchAtmList.this); protected void onPreExecute() { this.dialog.setMessage("Determining your location..."); this.dialog.show(); } protected Void doInBackground(Context... params) { LocationHelper location = new LocationHelper(); location.getLocation(params[0], locationResult); return null; } protected void onPostExecute(final Void unused) { if(this.dialog.isShowing()) { this.dialog.dismiss(); } useLocation(); //does the stuff that requires current location } } public LocationResult locationResult = new LocationResult() { @Override public void gotLocation(final Location location) { currentLocation = location; } }; 

UbicaciónHelper class

  package org.xxx.xxx.utils; import java.util.Timer; /* imports */ public class LocationHelper { LocationManager locationManager; private LocationResult locationResult; boolean gpsEnabled = false; boolean networkEnabled = false; public boolean getLocation(Context context, LocationResult result) { locationResult = result; if(locationManager == null) { locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); } //exceptions thrown if provider not enabled try { gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } catch (Exception ex) {} try { networkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); } catch (Exception ex) {} //dont start listeners if no provider is enabled if(!gpsEnabled && !networkEnabled) { return false; } if(gpsEnabled) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); } if(networkEnabled) { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork); } GetLastLocation(); return true; } LocationListener locationListenerGps = new LocationListener() { public void onLocationChanged(Location location) { locationResult.gotLocation(location); locationManager.removeUpdates(this); locationManager.removeUpdates(locationListenerNetwork); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extra) {} }; LocationListener locationListenerNetwork = new LocationListener() { public void onLocationChanged(Location location) { locationResult.gotLocation(location); locationManager.removeUpdates(this); locationManager.removeUpdates(locationListenerGps); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extra) {} }; private void GetLastLocation() { locationManager.removeUpdates(locationListenerGps); locationManager.removeUpdates(locationListenerNetwork); Location gpsLocation = null; Location networkLocation = null; if(gpsEnabled) { gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); } if(networkEnabled) { networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } //if there are both values use the latest one if(gpsLocation != null && networkLocation != null) { if(gpsLocation.getTime() > networkLocation.getTime()) { locationResult.gotLocation(gpsLocation); } else { locationResult.gotLocation(networkLocation); } return; } if(gpsLocation != null) { locationResult.gotLocation(gpsLocation); return; } if(networkLocation != null) { locationResult.gotLocation(networkLocation); return; } locationResult.gotLocation(null); } public static abstract class LocationResult { public abstract void gotLocation(Location location); } } 

Esto realmente parece un gran esfuerzo sólo para obtener la ubicación actual una vez? ¿No necesito actualizaciones ni nada? ¿No hay una manera más simple de tener la aplicación de esperar a un resultado? He estado atrapado en esto durante tanto tiempo.

  • Intervalo de actualización en requestLocationUpdates
  • ¿Dónde guardar los puntos GPS de Android (latitud, longitud)?
  • ¿Cómo puedo activar o desactivar el GPS mediante programación en Android?
  • Cómo activar mediante programación GPS en Android Cupcake
  • Android cómo detener gps
  • Gps vuelve un día antes?
  • Android Fake GPS aplicaciones de ubicación ya no funcionan
  • ¿Se puede ampliar el tamaño de la superposición con el mapa de google en android?
  • 3 Solutions collect form web for “Android encuentra la ubicación GPS una vez, muestra el diálogo de carga”

    Utilice un AsyncTask y use tanto network_provider como gps_provider , lo que significa dos oyentes. Gps lleva más tiempo para obtener una solución, tal vez a veces un minuto y sólo funciona al aire libre, mientras que la red tiene una ubicación bastante rápido.

    Un buen ejemplo de código está aquí: ¿Cuál es la manera más simple y más robusta de obtener la ubicación actual del usuario en Android?

    Para AsyncTask, mira http://developer.android.com/reference/android/os/AsyncTask.html

    También hay muchos ejemplos de código aquí en SO para él, por ejemplo aquí: Android Mostrar un diálogo hasta que un hilo se hace y luego continuar con el programa

    EDIT: código de concepto:

    Agregar variable de clase

     boolean hasLocation = false; 

    Llame a onCreate (no en AsyncTask):

     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 

    Entonces en locationListener.onLocationChanged, cambie el valor una vez que se encuentra una ubicación:

     boolean hasLocation = false; 

    AsyncTask: dejar como está, pero no llamar

     LocationHelper location = new LocationHelper(); location.getLocation(params[0], locationResult); 

    Allí, en lugar de hacer

     Long t = Calendar.getInstance().getTimeInMillies(); while (!hasLocation && Calendar.getInstance().getTimeInMillies()-t<30000)) { Thread.Sleep(1000); }; 

    Probablemente con un retraso en el medio sería suficiente.

    Todavía no me gusta cómo funciona esto en absoluto y parece mucho más complicado de lo que debería ser, pero hasta que alguien ofrece una mejor manera de tener que trabajar por ahora …

    Si alguien se encuentra con esto y sugieren un resultado mucho mejor limpiador para obtener las coordenadas de ubicación actual del usuario sólo una vez y luego dejar de buscar que sería muy apreciado!

     private LocationControl locationControlTask; private boolean hasLocation = false; LocationHelper locHelper; 

    De onCreate () llamo

     locHelper = new LocationHelper(); locHelper.getLocation(context, locationResult); locationControlTask = new LocationControl(); locationControlTask.execute(this); 

    Entonces tengo una clase particular LocationControl

     private class LocationControl extends AsyncTask<Context, Void, Void> { private final ProgressDialog dialog = new ProgressDialog(activityname.this); protected void onPreExecute() { this.dialog.setMessage("Searching"); this.dialog.show(); } protected Void doInBackground(Context... params) { //Wait 10 seconds to see if we can get a location from either network or GPS, otherwise stop Long t = Calendar.getInstance().getTimeInMillis(); while (!hasLocation && Calendar.getInstance().getTimeInMillis() - t < 15000) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }; return null; } protected void onPostExecute(final Void unused) { if(this.dialog.isShowing()) { this.dialog.dismiss(); } if (currentLocation != null) { useLocation(); } else { //Couldn't find location, do something like show an alert dialog } } } 

    Entonces una localizaciónResult ..

     public LocationResult locationResult = new LocationResult() { @Override public void gotLocation(final Location location) { currentLocation = new Location(location); hasLocation = true; } }; 

    También para evitar que usted tire de su cabello como lo hice durante años, recuerde detener la tarea locationcontrol si alguien deja la actividad temprano y también detener las actualizaciones de ubicación para detener el GPS de ejecutar cuando el usuario se va. En onStop () haz algo como esto:

     locHelper.stopLocationUpdates(); locationControlTask.cancel(true); 

    También stopLocationUpdates en la clase Ayudante de ubicación hace lo siguiente:

     public void stopLocationUpdates() { locationManager.removeUpdates(locationListenerGps); locationManager.removeUpdates(locationListenerNetwork); } 

    Buena suerte con él, lo necesitaba …

    En lugar de crear un AsyncTask, ¿por qué no creó un cuadro ProgressDialog y lo public void gotLocation(final Location location){} en public void gotLocation(final Location location){} ? También puede agregar un onCancelListener al cuadro ProgressDialog y cancelar cualquier solicitud de ubicación actual.

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.