La LocationManager
API en Android parece un poco difícil de usar para una aplicación que solo necesita una aproximación ocasional y aproximada de la ubicación del usuario.
La aplicación en la que estoy trabajando no es realmente una aplicación de ubicación per se, pero necesita obtener la ubicación del usuario para mostrar una lista de empresas cercanas. No necesita preocuparse si el usuario se está moviendo o algo así.
Esto es lo que me gustaría hacer:
- Mostrar al usuario una lista de ubicaciones cercanas.
- Precargue la ubicación del usuario para que cuando la necesite en
Activity
X, esté disponible. - No me importa particularmente la precisión o frecuencia de las actualizaciones. Solo agarrar una ubicación es suficiente siempre que no esté lejos. Tal vez si quiero ser elegante actualizaré la ubicación una vez cada pocos minutos, pero no es una gran prioridad.
- Funciona para cualquier dispositivo siempre que tenga un GPS o un proveedor de ubicación de red.
Parece que no debería ser tan difícil, pero me parece que tengo que conectar dos proveedores de ubicación diferentes (GPS y RED) y administrar el ciclo de vida de cada uno. No solo eso, sino que tengo que duplicar el mismo código en múltiples actividades para satisfacer el # 2. He intentado usar getBestProvider()
en el pasado para reducir la solución a solo usar un proveedor de ubicación, pero eso parece solo darle el mejor proveedor "teórico" en lugar del proveedor que realmente le dará los mejores resultados.
¿Hay una manera más simple de lograr esto?
Respuestas:
Esto es lo que hago:
Así es como uso mi clase:
Y aquí está la clase MyLocation:
Alguien también puede querer modificar mi lógica. Por ejemplo, si recibe una actualización del proveedor de red, no detenga a los oyentes sino que continúe esperando. El GPS proporciona datos más precisos, por lo que vale la pena esperarlo. Si transcurre el tiempo y tiene una actualización de la red pero no del GPS, puede usar el valor proporcionado por la red.
Un enfoque más es utilizar LocationClient http://developer.android.com/training/location/retrieve-current.html . Pero requiere que la aplicación Google Play Services esté instalada en el dispositivo del usuario.
fuente
Después de buscar la mejor implementación, cómo obtener la mejor ubicación precisa del usuario, logré combinar los mejores métodos y llegar a la siguiente clase:
Esta clase intenta conectarse a los
min_gps_sat_count
satélites si el GPS está habilitado. Else vuelve a laLocationManager.getBestProvider()
ubicación. ¡Comprueba el código!fuente
import java.util.Iterator; import android.content.Context; import android.location.Criteria; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler;
Con la solución de Fedor, he experimentado la ejecución múltiple de la devolución de llamada
gotLocation
. Parece ser debido a una condición de carrera en elLocationListener.onLocationChanged
método anulado , cuando el método gotLocation es 'lo suficientemente largo' . No estoy seguro, pero supongo queremoveUpdates
evita la puesta en cola de nuevos mensajes en la cola Looper, pero no elimina los que ya están en cola pero que aún no se han consumido. De ahí la condición de carrera.Para reducir la probabilidad de este comportamiento incorrecto, es posible llamar a removeUpdates antes de activar el evento onLocationChanged, pero aún tenemos la condición de carrera.
La mejor solución que encontré es reemplazar
requestLocationUpdates
conrequestSingleUpdate
.Esta es mi versión, basada en la solución de Fedor, que usa un controlador para enviar un mensaje al hilo del looper:
Utilizo esta clase desde un hilo looper personalizado, como el siguiente:
donde Coordinates es una clase simple con dos propiedades: latitud y longitud.
fuente
He creado una pequeña aplicación con una descripción paso a paso para obtener las ubicaciones actuales de las coordenadas GPS.
Ejemplo de código fuente completo en la siguiente URL:
Vea cómo funciona:
Todo lo que necesitamos hacer es agregar este permiso en el archivo de manifiesto
y crear una instancia de LocationManager como esta
Verifique que el GPS esté habilitado o no
luego implemente LocationListener y obtenga coordenadas
aquí está el código de muestra para hacer
fuente
Siempre puede usar LocationManager.getLastKnownLocation () pero, como dice, podría estar desactualizado.
Y una forma simple de obtener una ubicación general podría ser registrarse en la red (generalmente bastante rápido).
y luego haciendo
en el
onLocationChanged()
método del oyente.fuente
He escrito un tutorial detallado que cubre la ubicación actual aquí en demonuts.com . Puede encontrar más descripciones aquí y también puede descargar el código fuente completo de demostración para una mejor comprensión.
Ya hay muchas respuestas allí, pero quiero mostrar la última forma de obtener la ubicación utilizando la API de Google, para que los nuevos programadores puedan usar un nuevo método:
En primer lugar, pon esto en el archivo gradle
luego implemente las interfaces necesarias
declarar instancias
poner esto en
onCreate()
Por fin, anule los métodos necesarios
No olvide iniciar el GPS en su dispositivo antes de ejecutar la aplicación.
fuente
Actualmente podemos usar los dos proveedores (GPS y RED). Y solo comparten un oyente público:
Esto es necesario porque el
OnLocationChanged()
método siempre debe llamarse a tiempo.fuente
No estoy seguro de si los Servicios basados en la ubicación pueden obtener la ubicación de otras infraestructuras que no sean GPS, pero de acuerdo con ese artículo, parece posible:
fuente
Use el siguiente código, le dará el mejor proveedor disponible:
fuente
La forma recomendada de hacer esto es usar
LocationClient
:Primero, defina los valores del intervalo de actualización de ubicación. Ajusta esto a tus necesidades.
Tenga su
Activity
implementaciónGooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
yLocationListener
.Luego, configure a
LocationClient
en elonCreate()
método de suActivity
:Agregue los métodos requeridos a su
Activity
;onConnected()
es el método que se llama cuando seLocationClient
conecta.onLocationChanged()
es donde recuperarás la ubicación más actualizada.Asegúrese de conectar / desconectar
LocationClient
el dispositivo, de modo que solo use una batería adicional cuando sea absolutamente necesario y que el GPS no funcione indefinidamente. ElLocationClient
debe estar conectado para obtener datos de él.Obtenga la ubicación del usuario. Primero intente usar el
LocationClient
; si eso falla, recurra alLocationManager
.fuente
Aunque la respuesta ya se da aquí. Solo quería compartir esto con el mundo en caso de que surja tal escenario.
Mi requisito era que necesitaba obtener la ubicación actual de un usuario dentro de 30 a 35 segundos como máximo, así que aquí está la solución que tomé después de la Respuesta de Nirav Ranpara .
1. Hice MyLocationManager.java clase que se encarga de todas las cosas y la Red GPS
2. Hice una interfaz (devolución de llamada) OnLocationDetectectionListener.java para comunicar los resultados al fragmento o actividad de llamada
3. Luego hice una actividad MainAppActivty.java que implementa la
OnLocationDetectectionListener
interfaz y así es como recibo mi ubicación en ella4. Agregue los siguientes permisos a su archivo de manifiesto
Espero que esto sea útil para otros :)
fuente
Desde hace más de un año, estaba usando la combinación de GPS_PROVIDER y NETWORK_PROVIDER para obtener la ubicación actual y funcionaba bien, pero desde los últimos meses obtengo la ubicación después de un largo retraso, así que cambié al último API FusedLocationProviderClient y Funciona bastante bien.
Aquí está la clase que escribí para obtener la ubicación actual usando FusedLocationProviderClient. En el siguiente código, utilicé un temporizador para esperar mientras obtenía la ubicación actual, programé el temporizador con 15 segundos de retraso, puede cambiarlo de acuerdo con usted.
Y llamado esto por actividad, aquí está el código
Agregue las siguientes entradas en AndroidManifest.xml
fuente
fuente
Este es el código que proporciona la ubicación actual del usuario
crear Maps Activty:
main.xml:
y defina el siguiente permiso en manifiesto:
fuente
Esta es la forma en que solicito permisos de usuario.
Fuera de la etiqueta de su aplicación en AndroidManifest.xml, agregue estas solicitudes de permiso.
Luego agregue las dependencias de Ubicación de Google en el archivo de App Gradle.
Ahora declare algunas variables globales.
En el método OnCreate de su actividad (no pude formatear el código correctamente, disculpa por eso)
Ahora crea ambas funciones.
Segundo método
Para Constant.kt
fuente
Mejoras en la solución de @ Fedor. En lugar de solicitar una ubicación con un intervalo de tiempo '0' y una distancia '0', podemos usar el método requestSingleUpdate del administrador de ubicación . Código actualizado (versión kotlin)
Para obtener la ubicación, solo tiene que llamar al método getLocation como:
Nota: Antes de llamar al método getLocation, se debe otorgar el permiso de ubicación requerido.
fuente
Para obtener y mostrar la ubicación actual del usuario, también puede usar
MyLocationOverlay
. Suponga que tiene unmapView
campo en su actividad. Todo lo que debe hacer para mostrar la ubicación del usuario es lo siguiente:Esto obtiene la ubicación actual desde el GPS o la red. Si ambos fallan,
enableMyLocation()
volveráfalse
.En cuanto a la ubicación de las cosas alrededor del área, una
ItemizedOverlay
debería hacer el truco.Espero no haber entendido mal su pregunta. Buena suerte.
fuente
EDITAR: actualizado con la última API de servicio de ubicación de la biblioteca de Google Play Services (julio de 2014)
Le recomendaría que use la nueva API de servicio de ubicación , disponible en la biblioteca de servicios de Google Play, que proporciona un marco más potente y de alto nivel que automatiza tareas como la elección del proveedor de ubicación y la administración de energía. De acuerdo con la documentación oficial: "... La API de ubicación le facilita la creación de aplicaciones que reconocen la ubicación, sin necesidad de centrarse en los detalles de la tecnología de ubicación subyacente. También le permiten minimizar el consumo de energía mediante el uso de todas las capacidades del hardware del dispositivo ".
Para más información visite: Cómo hacer que su aplicación conozca la ubicación
Para ver un ejemplo completo con la última visita a la API del servicio de ubicación: la clase Android LocationClient está en desuso pero se usa en la documentación
fuente
La forma más simple y mejor para GeoLocation.
fuente
Un poco tarde aquí, pero lo que haría en tal situación es usar la API de Google Maps y marcar las ubicaciones cercanas con la API lat y long de Google Maps. Además, la experiencia del usuario es mejor si puede mostrar su ubicación en un mapa. No es necesario preocuparse por la actualización de la ubicación del usuario o el registro con la API de Android. Deje que Google Maps se encargue de lo interno por usted.
Es posible que @emmby lo haya resuelto en su aplicación, pero para futuras referencias, mire la API de Google Maps para obtener información específica sobre la ubicación.
Editar: enlace para mostrar la ubicación del usuario en Google Maps
fuente
Requiere muchas cosas en su lugar para obtener actualizaciones de ubicación en Android, requiere un montón de código bolierplate.
Necesitas cuidar
He creado Android-EasyLocation (pequeña biblioteca de Android) que se encargará de todo esto y puede centrarse en la lógica empresarial.
Todo lo que necesita es extender EasyLocationActivity y esto
o
Consulte la aplicación de muestra y los pasos necesarios aquí en https://github.com/akhgupta/Android-EasyLocation
fuente
Esto es lo que hago:
mFinalLocation
).onDestroy()
método de servicio, deja de escuchar las actualizaciones de ubicación para cada uno de los proveedores.A continuación se muestra el código de servicio. Puede ejecutarlo según la frecuencia de actualización de ubicación que necesite.
fuente
Versión de Kotlin de @Fedor Greate responde:
uso de la clase:
MyLocation
Clase :fuente
En la clase de actividad realiza un método personalizado:
Hacer un nombre de clase definido por el usuario LocationGetter: -
fuente
Mediante el uso de FusedLocationProviderApi, que es la última API y la mejor entre las posibilidades disponibles para obtener ubicación en Android. agregue esto en el archivo build.gradle
puede obtener el código fuente completo en esta url http://javapapers.com/android/android-location-fused-provider/
fuente
Recientemente refactorizado para obtener la ubicación del código, aprender algunas buenas ideas y finalmente lograr una biblioteca y demostración relativamente perfecta.
Código completo: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java
* Cada solicitud para completar la ubicación, es mejor eliminar las actualizaciones, de lo contrario la barra de estado del teléfono siempre mostrará el icono de posicionamiento.
fuente
Después de ver todas las respuestas y preguntas ( más simple y robusto ). Me hicieron clic sobre solo la biblioteca Android-ReactiveLocation .
Cuando hice una aplicación de seguimiento de ubicación. Luego me di cuenta de que es muy típico manejar el seguimiento de ubicación con batería optimizada.
Por lo tanto, quiero contarles a los estudiantes de primer año y también a los desarrolladores que no desean mantener su código de ubicación con futuras optimizaciones. Usa esta biblioteca.
Dependencias para poner en el nivel de aplicación build.gradle
Pros para usar esta lib:
fuente