rastrear por localizar internet google encontrar dispositivos dispositivo celular administrador android gps progressdialog locationlistener

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



rastrear celular (3)

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

Conseguí que los elementos más cercanos funcionen bien, pero por el momento solo uso una ubicación de latitud y longitud codificada, pero ahora es el momento de implementar la ubicación real.

¿Puede alguien proporcionar un ejemplo de cómo hacer que la aplicación encuentre la buena ubicación actual en segundo plano y hacer que la aplicación espere? Solo necesito la ubicación una vez que no se actualice a medida que la persona se mueve. He implementado un servicio de escucha de ubicación, sin embargo, entiendo que obtener una corrección de GPS puede ser lento. He visto otros ejemplos utilizando la última ubicación conocida o implementando el detector de ubicación que continúa ejecutándose y actualizándose, sin embargo, ya que mi Actividad necesita las coordenadas de la ubicación antes de poder mostrar cualquier cosa que la aplicación simplemente bloquee. Necesito mostrar un diálogo de progreso mientras está buscando.

¿Cómo puedo hacer que el listador de ubicación se ejecute una vez en segundo plano y luego elimine las actualizaciones de ubicación una vez que encuentre la ubicación? Necesito que el resto de la aplicación espere hasta que tenga una ubicación de GPS o un tiempo de espera después de unos 20-30 segundos. Me gustaría un ProgressDialog para que el usuario sepa que algo está pasando, pero solo tiene que ser la animación de carga giratoria, no un porcentaje ni nada. Si es posible, me gustaría que el usuario pueda cancelar el cuadro de diálogo si está cansado de esperar, que puede buscar escribiendo suburbio, etc.

He estado tratando de hacerlo con hilos, pero se está complicando mucho más de lo que creo que debería ser y todavía no funciona. En iPhone esto es mucho más simple?

¿Alguien puede proporcionar una buena manera de hacer esto? He estado arrancándome el pelo durante una semana y realmente me está retrasando para el resto de la fecha de finalización de la aplicación.

En resumen quiero:
* Encontrar coordenadas actuales
* Mostrar el diálogo de progreso al obtener la ubicación
* ¿La aplicación puede esperar una ubicación exitosa o darse por vencida después de cierto tiempo?
* Si es exitoso: descarte el diálogo de progreso y use las coordenadas para ejecutar mis otros métodos para encontrar elementos cercanos.
* Si no se pudo obtener la ubicación: descartar el diálogo de progreso y mostrar un mensaje de error, y alentar al usuario a usar el menú para ir a la actividad de búsqueda.
* Use estas coordenadas si el usuario elige la vista del mapa del menú, para mostrar la ubicación actual en el mapa y los alfileres que se han caído en todos los elementos cercanos utilizando sus coordenadas de la base de datos.

Gracias chicos, espero que me haya explicado lo suficientemente bien. Cualquier pregunta solo pregunte, volveré a revisar regularmente ya que estoy ansioso por completar esta parte. Aclamaciones

EDITAR
Código según lo 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; } };

LocationHelper 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 solo para obtener la ubicación actual una vez? No necesito actualizaciones ni nada? ¿No hay una forma más sencilla de hacer que la aplicación espere un resultado? He estado atrapado en esto durante tanto tiempo.


En lugar de crear una AsyncTask, ¿por qué no creó un cuadro de 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.


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

Si alguien se encuentra con esto y sugiere un resultado mucho mejor y más limpio para obtener las coordenadas de la ubicación actual del usuario solo una vez, ¡entonces deje de buscar, eso sería muy apreciado!

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

Desde onCreate () llamo

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

Entonces tengo una clase privada 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 un locationResult ..

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

Además, para evitar que te saques el pelo como lo hice durante años, recuerda detener la tarea de control de ubicación si alguien abandona la actividad antes de tiempo y también detiene las actualizaciones de ubicación para evitar que el GPS se ejecute cuando el usuario se retire. En onStop () haz algo como esto:

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

Además, stopLocationUpdates en la clase Ayudante de ubicación hace lo siguiente:

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

Buena suerte con eso, lo necesitaba ...


Use una AsyncTask y use tanto network_provider como gps_provider , lo que significa dos oyentes. gps tarda más en obtener una solución, tal vez a veces un minuto y solo funciona en exteriores, mientras que la red obtiene una ubicación bastante rápida.

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

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

También hay muchos ejemplos de código aquí en SO, por ejemplo aquí: Android Muestra un cuadro de diálogo hasta que se completa un hilo y luego continúa con el programa

EDITAR: concepto de código:

añadir variable de clase

boolean hasLocation = false;

llamar en onCreate (no en AsyncTask):

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

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

boolean hasLocation = false;

AsyncTask: déjelo como está, pero no llame

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.