L' LocationManager
API sur Android semble être un peu pénible à utiliser pour une application qui n'a besoin que d'une approximation occasionnelle et approximative de l'emplacement de l'utilisateur.
L'application sur laquelle je travaille n'est pas vraiment une application de localisation en soi, mais elle doit obtenir l'emplacement de l'utilisateur afin d'afficher une liste des entreprises à proximité. Il n'a pas besoin de s'inquiéter si l'utilisateur se déplace ou quelque chose comme ça.
Voici ce que j'aimerais faire:
- Montrez à l'utilisateur une liste de lieux à proximité.
- Préchargez l'emplacement de l'utilisateur de sorte que lorsque j'en aurai besoin dans
Activity
X, il sera disponible. - Je ne me soucie pas particulièrement de l'exactitude ou de la fréquence des mises à jour. Il suffit de saisir un emplacement pour autant qu'il ne soit pas loin. Peut-être que si je veux être fantaisiste, je mettrai à jour l'emplacement une fois toutes les quelques minutes, mais ce n'est pas une énorme priorité.
- Fonctionne pour n'importe quel appareil tant qu'il dispose d'un GPS ou d'un fournisseur de localisation réseau.
Il semble que cela ne devrait pas être si difficile, mais il me semble que je dois faire tourner deux fournisseurs de localisation différents (GPS et RÉSEAU) et gérer le cycle de vie de chacun. Non seulement cela, mais je dois dupliquer le même code dans plusieurs activités pour satisfaire # 2. J'ai essayé d'utiliser getBestProvider()
dans le passé pour réduire la solution à un seul fournisseur de localisation, mais cela ne semble vous donner que le meilleur fournisseur "théorique" plutôt que le fournisseur qui va réellement vous donner les meilleurs résultats.
Existe-t-il un moyen plus simple d'accomplir cela?
Réponses:
Voici ce que je fais:
Voici comment j'utilise ma classe:
Et voici la classe MyLocation:
Quelqu'un peut aussi vouloir modifier ma logique. Par exemple, si vous obtenez une mise à jour du fournisseur de réseau, n'arrêtez pas les écouteurs mais continuez d'attendre. Le GPS fournit des données plus précises, il vaut donc la peine de les attendre. Si la minuterie s'est écoulée et que vous avez une mise à jour du réseau mais pas du GPS, vous pouvez utiliser la valeur fournie par le réseau.
Une autre approche consiste à utiliser LocationClient http://developer.android.com/training/location/retrieve-current.html . Mais cela nécessite que Google Play Services apk soit installé sur la machine utilisateur.
la source
Après avoir recherché la meilleure mise en œuvre pour obtenir le meilleur emplacement utilisateur précis, j'ai réussi à combiner toutes les meilleures méthodes et à trouver la classe suivante:
Cette classe essaie de se connecter aux
min_gps_sat_count
satellites si le GPS est activé. Sinon retourne l'LocationManager.getBestProvider()
emplacement. Vérifiez le code!la source
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;
Avec la solution de Fedor, j'ai connu plusieurs exécutions du rappel
gotLocation
. Cela semble être dû à une condition deLocationListener.onLocationChanged
concurrence dans la méthode remplacée , lorsque la méthode gotLocation est «suffisamment longue» . Je ne suis pas sûr, mais je suppose que celaremoveUpdates
empêche la mise en file d'attente de nouveaux messages dans la file d'attente du Looper, mais cela ne supprime pas ceux déjà mis en file d'attente mais pas encore consommés. D'où la condition de concurrence.Pour réduire la probabilité de ce comportement incorrect, il est possible d'appeler removeUpdates avant de déclencher l'événement onLocationChanged, mais nous avons toujours la condition de concurrence critique.
La meilleure I de Trouvées solution est de remplacer
requestLocationUpdates
avecrequestSingleUpdate
.Voici ma version, basée sur la solution de Fedor, utilisant un gestionnaire pour envoyer un message au thread du looper:
J'utilise cette classe à partir d'un fil de boucle personnalisé, comme le suivant:
où Coordonnées est une classe simple avec deux propriétés: latitude et longitude.
la source
J'ai créé une petite application avec une description étape par étape pour obtenir les coordonnées GPS des emplacements actuels.
Exemple de code source complet dans l'URL ci-dessous:
Regarde comment ça marche :
Tout ce que nous devons faire est d'ajouter cette autorisation dans le fichier manifeste
et créer une instance LocationManager comme celle-ci
Vérifiez que le GPS est activé ou non
puis implémentez LocationListener et obtenez les coordonnées
voici l'exemple de code à faire
la source
Vous pouvez toujours simplement utiliser LocationManager.getLastKnownLocation () mais comme il est dit, il pourrait être obsolète.
Et un moyen simple d'obtenir un emplacement général pourrait être l'inscription au réseau (généralement assez rapide).
puis faire
dans la
onLocationChanged()
méthode de l'auditeur.la source
J'ai écrit un tutoriel détaillé couvrant l'emplacement actuel ici sur demonuts.com. Vous pouvez trouver plus de description ici et vous pouvez également télécharger le code source de la démo entière pour une meilleure compréhension.
Il y a déjà beaucoup de réponses, mais je veux montrer la dernière façon d'obtenir l'emplacement à l'aide de l'API Google, afin que les nouveaux programmeurs puissent utiliser une nouvelle méthode:
Tout d'abord, mettez-le dans un fichier gradle
puis implémenter les interfaces nécessaires
déclarer des instances
mettre ça dans
onCreate()
Enfin, remplacez les méthodes nécessaires
N'oubliez pas de démarrer le GPS sur votre appareil avant d'exécuter l'application.
la source
En fait, nous pouvons utiliser les deux fournisseurs (GPS et RÉSEAU). Et ils partagent juste un auditeur public:
Cela est nécessaire car la
OnLocationChanged()
méthode doit toujours être appelée à temps.la source
Je ne sais pas si les services géodépendants peuvent obtenir l'emplacement d'autres infrastructures autres que le GPS, mais selon cet article, il semble possible:
la source
Utilisez le code ci-dessous, il donnera le meilleur fournisseur disponible:
la source
Pour ce faire, il est recommandé d'utiliser
LocationClient
:Tout d'abord, définissez les valeurs d'intervalle de mise à jour de l'emplacement. Adaptez cela à vos besoins.
Demandez à votre
Activity
mise en œuvreGooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
etLocationListener
.Ensuite, configurez un
LocationClient
dans laonCreate()
méthode de votreActivity
:Ajoutez les méthodes requises à votre
Activity
;onConnected()
est la méthode qui est appelée lors de laLocationClient
connexion.onLocationChanged()
est l'endroit où vous récupérerez l'emplacement le plus récent.Assurez-vous de connecter / déconnecter le
LocationClient
afin qu'il n'utilise de batterie supplémentaire qu'en cas de nécessité absolue et que le GPS ne fonctionne pas indéfiniment. LeLocationClient
doit être connecté pour en obtenir des données.Obtenez l'emplacement de l'utilisateur. Essayez d'abord d'utiliser le
LocationClient
; si cela échoue, revenez auLocationManager
.la source
Même si la réponse est déjà donnée ici. Je voulais juste partager cela avec le monde au cas où un tel scénario se présenterait.
Mon exigence était que je devais obtenir la position actuelle d'un utilisateur dans les 30 à 35 secondes au maximum, alors voici la solution que j'ai faite à la suite de la réponse de Nirav Ranpara .
1. J'ai créé la classe MyLocationManager.java qui gère tous les trucs GPS et réseau
2. J'ai créé une interface (rappel) OnLocationDetectectionListener.java afin de communiquer les résultats au fragment ou à l'activité appelante.
3. Ensuite, j'ai fait une activité MainAppActivty.java qui implémente l'
OnLocationDetectectionListener
interface et voici comment je reçois mon emplacement dedans4. Ajoutez les autorisations suivantes à votre fichier manifeste
J'espère que cela sera utile aux autres :)
la source
Depuis plus d'un an, j'utilisais la combinaison de GPS_PROVIDER et NETWORK_PROVIDER pour obtenir l'emplacement actuel et cela fonctionnait bien, mais depuis quelques mois, j'obtiens l'emplacement après un long délai, j'ai donc basculé vers la dernière API FusedLocationProviderClient et cela fonctionne plutôt bien.
Voici la classe que j'ai écrite pour obtenir l'emplacement actuel en utilisant FusedLocationProviderClient. Dans le code ci-dessous, j'ai utilisé un minuteur pour attendre pendant un certain temps pour obtenir l'emplacement actuel, j'ai programmé un retard de 15 secondes, vous pouvez le changer selon vous.
Et appelé cela de l'activité, voici le code
Ajoutez les entrées suivantes dans AndroidManifest.xml
la source
la source
Ceci est le code qui fournit l'emplacement actuel de l'utilisateur
créer Maps Activty:
main.xml:
et définissez l'autorisation suivante dans le manifeste:
la source
C'est ainsi que je demande des autorisations utilisateur.
En dehors de votre balise d'application dans AndroidManifest.xml, ajoutez ces demandes d'autorisation.
Ajoutez ensuite les dépendances de localisation de Google dans le fichier App Gradle.
Déclarez maintenant quelques variables globales.
Dans la méthode OnCreate de votre activité (je n'ai pas pu formater correctement le code, excuses pour cela)
Créez maintenant les deux fonctions.
Deuxième méthode
Pour Constant.kt
la source
Améliorations de la solution @ Fedor. Plutôt que de demander un emplacement avec un intervalle de temps «0» et une distance «0», nous pouvons utiliser la méthode requestSingleUpdate du gestionnaire d' emplacement . Code mis à jour (version kotlin)
Pour obtenir l'emplacement, il suffit d'appeler la méthode getLocation comme -
Remarque: Avant d'appeler la méthode getLocation, l'autorisation de localisation requise doit être accordée.
la source
Pour obtenir et afficher l'emplacement actuel de l'utilisateur, vous pouvez également utiliser
MyLocationOverlay
. Supposons que vous ayez unmapView
champ dans votre activité. Tout ce que vous devez faire pour afficher l'emplacement de l'utilisateur est le suivant:Cela obtient l'emplacement actuel à partir du GPS ou du réseau. Si les deux échouent,
enableMyLocation()
reviendrafalse
.Quant à l'emplacement des choses autour de la zone, un
ItemizedOverlay
devrait faire l'affaire.J'espère que je n'ai pas mal compris votre question. Bonne chance.
la source
EDIT: mis à jour avec la dernière API de service de localisation de la bibliothèque des services Google Play (juillet 2014)
Je vous recommande d'utiliser la nouvelle API de service de localisation , disponible dans la bibliothèque des services Google Play, qui fournit un cadre plus puissant et de haut niveau qui automatise des tâches telles que le choix du fournisseur de localisation et la gestion de l'alimentation. Selon la documentation officielle: "... L'API de localisation vous permet de créer facilement des applications sensibles à la localisation, sans avoir à vous concentrer sur les détails de la technologie de localisation sous-jacente. Elles vous permettent également de réduire la consommation d'énergie en utilisant toutes les fonctionnalités du matériel de l'appareil. "
Pour plus d'informations, visitez: Rendre votre application sensible à l'emplacement
Pour voir un exemple complet utilisant la dernière API de service de localisation, visitez: La classe Android LocationClient est déconseillée mais utilisée dans la documentation
la source
Moyen simple et meilleur pour GeoLocation.
la source
Un peu tard ici, mais ce que je voudrais dans une telle situation, c'est d'utiliser l'API Google Maps et de marquer les emplacements à proximité à l'aide de l'API lat et longue de Google Maps. De plus, l'expérience utilisateur est meilleure si vous pouvez afficher sa position sur une carte. Pas besoin de s'inquiéter de la mise à jour de l'emplacement de l'utilisateur ou de fouiller avec l'API Android. Laissez google maps gérer les éléments internes pour vous.
@emmby a peut-être résolu le problème dans son application, mais pour référence future, jetez un œil à l'API Google maps pour des informations spécifiques à l'emplacement, ce que je recommande à mes collègues développeurs.
Modifier: lien pour afficher l'emplacement de l'utilisateur dans google maps
la source
Il nécessite beaucoup de choses en place pour obtenir des mises à jour de localisation dans Android, nécessite beaucoup de code bolierplate.
Vous devez prendre soin de
J'ai créé Android-EasyLocation (petite bibliothèque Android) qui s'occupera de tout cela et vous pourrez vous concentrer sur la logique métier.
Tout ce dont vous avez besoin est d'étendre EasyLocationActivity et cela
ou
Exemple d'application de paiement et étapes nécessaires ici à https://github.com/akhgupta/Android-EasyLocation
la source
Voici ce que je fais:
mFinalLocation
).onDestroy()
méthode de service, arrête d'écouter les mises à jour d'emplacement pour chacun des fournisseurs.Vous trouverez ci-dessous le code de service. Vous pouvez l'exécuter en fonction de la fréquence de mise à jour de l'emplacement dont vous avez besoin.
la source
Version Kotlin de @Fedor Greate réponse:
utilisation de la classe:
MyLocation
Classe:la source
Dans la classe d'activité crée une méthode personnalisée:
Faire un nom de classe défini par l'utilisateur LocationGetter: -
la source
En utilisant FusedLocationProviderApi qui est la dernière API et la meilleure parmi les possibilités disponibles pour obtenir une localisation dans Android. ajoutez ceci dans le fichier build.gradle
vous pouvez obtenir le code source complet par cette URL http://javapapers.com/android/android-location-fused-provider/
la source
Récemment refactorisé pour obtenir l'emplacement du code, apprendre quelques bonnes idées, et enfin réalisé une bibliothèque et une démo relativement parfaites.
Code complet: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java
* Chaque demande de compléter l'emplacement, il est préférable de supprimer les mises à jour, sinon la barre d'état du téléphone affichera toujours l'icône de positionnement.
la source
Après avoir vu toutes les réponses et la question (la plus simple et la plus robuste ). J'ai été cliqué sur la seule bibliothèque Android-ReactiveLocation .
Quand j'ai créé une application de suivi de position. Ensuite, j'ai réalisé que c'était très typique de gérer le suivi de localisation avec optimisé avec la batterie.
Je veux donc dire aux plus récents et aussi aux développeurs qui ne veulent pas conserver leur code de localisation avec de futures optimisations. Utilisez cette bibliothèque.
Dépendances à mettre au niveau de l'application build.gradle
Avantages d'utiliser cette lib:
la source