Tiempo de espera de Android GPS

Edit: Estoy reescribiendo esta pregunta porque aparentemente no estaba claro.

A veces, el servicio de GPS en los teléfonos Android tarda mucho tiempo en conseguir una solución. A veces es rápido, a veces toma horas. Sé y acepto esto.

Tengo una aplicación que hace muchas cosas. Una de las cosas que debe hacer es permitir al usuario hacer clic en un botón para enviar sus coordenadas actuales a un servidor. Lo que necesito son las coordenadas del teléfono cuando el usuario hace clic en el botón o dentro de un tiempo razonablemente corto después de eso.

Porque sé que conseguir una solución GPS no es instantánea y sé que podría tomar minutos o horas (durante el cual el usuario se ha movido una gran distancia), necesito codificar un tiempo de espera para esta función. Para esta función, simplemente no es aceptable cargar la ubicación GPS del usuario tres minutos (por ejemplo) después de hacer clic en el botón. Está bien si tarda 45 segundos, no está bien si se tarda 75 segundos. Está bien darle al usuario una notificación de error si la función no pudo obtener una ubicación lo suficientemente rápido.

Necesito una función para obtener la ubicación GPS y enviarla al servidor, a menos que se necesite más de un minuto .

Mi código original está abajo. He cambiado algunas cosas desde que lo publicaron. He añadido un temporizador en el método onStartCommand (). Inicie un TimerTask que después de 60 segundos llamará a mi método stop (). Al principio del método onLocationChanged (), cancelo el TimerTask.

Mi pregunta es: ¿Es el esquema de temporizador una buena manera de implementar este tiempo de espera? ¿Hay una mejor manera?

Pregunta original:

Estoy escribiendo una aplicación de Android que, entre otras cosas, necesita enviar las coordenadas GPS actuales a un servidor cuando el usuario se lo indique. Desde un menú contextual, ejecuto el servicio a continuación. El servicio es un LocationListener y solicita actualizaciones desde LocationManager. Cuando obtiene una ubicación (onLocationChanged ()), se elimina como un escucha y envía las coordenadas al servidor. Todo esto está funcionando.

Sin embargo, si las coordenadas GPS no están disponibles rápidamente, mi servicio sólo sigue funcionando hasta que se obtiene algo. Se sostiene la interfaz de usuario con un diálogo de progreso, que es molesto. Peor aún, si el usuario se ha movido desde el inicio del servicio, las primeras coordenadas GPS pueden estar equivocadas y la aplicación enviará datos incorrectos al servidor.

Necesito un tiempo de espera en el servicio. ¿Hay una buena manera de hacer eso? No soy muy experimentado con hilos. Creo que puedo ejecutar un Runnable en el método onStartCommand () que de alguna manera cuenta atrás de 30 segundos y, a continuación, si no hay ningún resultado GPS todavía, llame al servicio stop () de mi servicio. ¿Suena como la mejor manera de hacer esto?

Alternativamente, ¿es posible saber si el GPS no puede obtener una solución? ¿Cómo iba a hacer eso?

Editar: Para aclarar más, estoy buscando la mejor manera de "rendirse" en conseguir una ubicación después de una cierta cantidad de tiempo.

public class AddCurrentLocation extends Service implements LocationListener { Application app; LocationManager mLocManager; ProgressDialog mDialog; @Override public int onStartCommand(Intent intent, int arg0, int arg1) { app = getApplication(); // show progress dialog if (app.getScreen() != null) { mDialog = ProgressDialog.show(app.getScreen(), "", "Adding Location. Please wait...", true); } // find GPS service and start listening Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); String bestProvider = mLocManager.getBestProvider(criteria, true); mLocManager.requestLocationUpdates(bestProvider, 2000, 0, this); return START_NOT_STICKY; } private void stop() { mLocManager.removeUpdates(this); if (mDialog != null) { mDialog.dismiss(); } stopSelf(); } @Override public void onLocationChanged(Location location) { // done with GPS stop listening mLocManager.removeUpdates(this); sendLocation(location); // method to send info to server stop(); } // other required methods and sendLocation() ... } 

Eso no es realmente cómo funciona. En la mayoría de las situaciones, se tomará constantemente ese tiempo para obtener una solución GPS. Pero desde ese punto en cada actualización (cada 2 segundos en su código) será la posición actual de la persona. Y la primera solución que obtendrá será la posición actual de la persona, por lo que los datos no estarán "desactualizados".

Otra cosa. Si está ejecutando este código en un servicio no debe bloquear la interfaz de usuario con un diálogo de progreso y definitivamente no desde el servicio. Esa es una pérdida de memoria esperando a suceder. Sólo debe mostrar progreso si es algo que puede tardar 5 segundos como máximo y se ejecuta en un hilo en la actividad. Otra opción es mostrar el diálogo de progreso en la barra de título, y todavía dejar que el usuario interactúe con la aplicación (que es por eso que utiliza un servicio de todos modos). Mostrando progresos durante un largo período de tiempo realmente no es tan fácil de usar. Especialmente si cambian de alguna manera la orientación (quizás en caso de accidente) y luego su aplicación se bloquea debido a la manija de servicio al diálogo y tienen que empezar de nuevo.

Echa un vistazo a la aplicación Google I / O 2010 para ver un gran ejemplo de cómo una actividad debería funcionar con un servicio. Utiliza un servicio para retirar datos y muestra un progreso en el título mientras el servicio está realizando algún trabajo. Y todavía te permite hacer otras cosas en la aplicación.

Scott, hay muchos factores que afectan cuánto tiempo puede durar una primera corrección, o incluso si se puede lograr una solución, siendo los más comunes los obstáculos físicos entre el dispositivo y los satélites (como los edificios, las paredes del cañón, etc.).

No puedes controlar cuánto tarda el motor GPS en entregar una corrección, pero puedes saber cómo funciona, incluido el tiempo de la primera corrección:

 locationManager.addGpsStatusListener(gpsListener); // this reports on the status of the GPS engine, but does not enable additional controls private static final GpsStatus.Listener gpsListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { GpsStatus gpsStatus = locationManager.getGpsStatus(null); switch (event) { case GpsStatus.GPS_EVENT_STARTED: Log.i(TAG, "onGpsStatusChanged(): GPS started"); break; case GpsStatus.GPS_EVENT_FIRST_FIX: Log.i(TAG, "onGpsStatusChanged(): time to first fix in ms = " + gpsStatus.getTimeToFirstFix()); break; case GpsStatus.GPS_EVENT_SATELLITE_STATUS: // int maxSatellites = gpsStatus.getMaxSatellites(); // appears fixed at 255 // if (H.DEBUG) Log.d(TAG, "onGpsStatusChanged(): max sats = " + maxSatellites); if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): ##,used,s/n,az,el"); Iterable<GpsSatellite>satellites = gpsStatus.getSatellites(); Iterator<GpsSatellite>satI = satellites.iterator(); while (satI.hasNext()) { GpsSatellite satellite = satI.next(); if (H.VERBOSE) Log.d(TAG, "onGpsStatusChanged(): " + satellite.getPrn() + "," + satellite.usedInFix() + "," + satellite.getSnr() + "," + satellite.getAzimuth() + "," + satellite.getElevation()); // http://en.wikipedia.org/wiki/Global_Positioning_System: the almanac consists of coarse orbit and status information for each satellite // http://en.wikipedia.org/wiki/Ephemeris: the positions of astronomical objects in the sky at a given time // + "," + satellite.hasAlmanac() + "," + satellite.hasEphemeris()); } break; case GpsStatus.GPS_EVENT_STOPPED: Log.i(TAG, "onGpsStatusChanged(): GPS stopped"); break; } } }; 

Los eventos se generarán cuando el motor intente escuchar los satélites disponibles. En una prueba reciente de esto con los obstáculos de luz encontré que tomó 22,4 segundos para obtener una solución inicial, durante el cual 24 eventos SATELLITE_STATUS informando el acceso gradual de 8 satélites antes de recibir señales suficientemente limpias para lograr la corrección. Aquí está el último evento:

06-08 23: 23: 25.147, D, GPS, 22427, "onGpsStatusChanged (): ##, used, s / n, az, el" 06-08 23: 23: 25.147, D, GPS, 22427, onGpsStatusChanged (): 2, true, 26.0,57.0.73.0 "06-08 23: 23: 25.147, D, GPS, 22427," onGpsStatusChanged (): 4, true, 30.0,46.0.27.0 "06-08 23:23: 25.147, D, GPS, 22427, "onGpsStatusChanged (): 5, true, 19.0,144.0,25.0" 06-08 23: 23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 9, true, 22.0.202.0 , 22.0 "06-08 23: 23: 25.155, D, GPS, 22427," onGpsStatusChanged (): 10, true, 17.0.109.0.332.0 "06-08 23: 23: 25.155, D, GPS, 22427," onGpsStatusChanged (): 12, true, 32.0.320.0,80.0 "06-08 23: 23: 25.155, D, GPS, 22427," onGpsStatusChanged (): 29, true, 21.0.278.0,21.0 "06-08 23:23: 25.155, D, GPS, 22427, "onGpsStatusChanged (): 30, true, 31.0.312.0.43.0" 06-08 23: 23: 25.163, D, GpsLocationProvider, 1039, TTFF: 22457 06-08 23: 23: 25.194, I, GPS, 22427, onGpsStatusChanged (): tiempo para la primera corrección en ms = 22457

Tenga en cuenta que en el momento de la fijación, se obtendrá la ubicación actual, no donde una vez pudo haber sido. Creo que junto con lo que ya tienes puedes llegar ahora. O, echa un vistazo a cómo los profesionales lo hacen aquí .

Hay un ejemplo acerca de obtener la ubicación GPS con tiempo de espera.

http://sikazi.blogspot.com/2010/09/android-gps-timeout.html#more

He estado luchando con un problema similar y recientemente cambiado de un temporizador a un AlarmManager , que parece ser mucho más robusto. Eso podría ser excesivo para su situación (estoy usando esto para el muestreo de ubicación repetida), pero es posible que desee utilizar al menos un Handler lugar del temporizador. (Utilizar Handler.postDelayed .)

Basado en la respuesta a Shawn, empacar los parámetros en JSON y enviar los objetos JSON en el servidor

  • Android - Fused Location Provider Problemas de API con información de satélite (cuenta, señal, etc.)
  • Precisión de Android GPS
  • El emulador de Android no puede reconocer que el GPS está habilitado
  • Android GPS tarda un tiempo en ser preciso
  • Permisos de tiempo de ejecución de Android en las versiones de android debajo de M?
  • GPS VS acelerómetro para calcular la distancia
  • Desactivar / Comprobar la ubicación falsa (evitar la suplantación de gps)
  • Android onLocationUpdate no se llama con GPS_PROVIDER
  • Geolocation.watchposition no funciona con la ubicación basada en red desactivada
  • Q. Ubicación GPS de Android
  • Cómo obtener sellos horarios precisos desde la ubicación GPS de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.