Je souhaite créer une application centrée sur l'obtention de la position actuelle de l'utilisateur, puis sur les points d'intérêt (bars, restaurants, etc.) proches de lui via le Google Places API.
En cherchant sur le Web un endroit pour commencer, je suis tombé sur des tutoriels qui utilisaient la classe LocationManager
et sur d’autres qui utilisaient Services Google Play afin de trouver l’emplacement des utilisateurs.
À première vue, les deux font la même chose, mais comme je suis novice dans ce domaine, je suis un peu confuse et je ne sais pas quelle méthode convient le mieux à mes besoins. Alors, je veux vous demander:
Quelles sont les différences entre ces deux méthodes de recherche d'emplacements (le cas échéant)?
Emplacement de l'utilisateur sur Android
Obtenir l'emplacement de l'utilisateur sur Android est un peu moins simple que sur iOS. Pour créer la confusion, il existe deux manières totalement différentes de le faire. Le premier utilise Android API de Android.location.LocationListener
, et le second utilise les API de services Google Play com.google.Android.gms.location.LocationListener
. Passons en revue les deux.
API de localisation d’Android
Les API de localisation d’Android utilisent trois fournisseurs différents pour obtenir la localisation:
LocationManager.GPS_PROVIDER
- Ce fournisseur détermine la position à l'aide de satellites. Selon les conditions, ce fournisseur peut prendre un certain temps pour renvoyer un correctif d'emplacement.LocationManager.NETWORK_PROVIDER
- Ce fournisseur détermine l'emplacement en fonction de la disponibilité de la tour de téléphonie cellulaire et des points d'accès WiFi. Les résultats sont récupérés au moyen d'une recherche sur le réseau.LocationManager.PASSIVE_PROVIDER
- Ce fournisseur renvoie les emplacements générés par d'autres fournisseurs. Vous recevez passivement des mises à jour d'emplacement lorsque d'autres applications ou services le demandent, sans demander vous-même les emplacements.En résumé, vous obtenez un objet de LocationManager
du système, implémentez la LocationListener
et appelez la requestLocationUpdates
sur la LocationManager
.
Voici un extrait de code:
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
Guide de l’API de Google sur les stratégies de localisation explique assez bien le code. Mais ils mentionnent également que dans la plupart des cas, vous obtiendrez de meilleures performances de la batterie, ainsi qu'une précision plus appropriée, en utilisant API de Google Location Services . Maintenant la confusion commence!
L’API des services de localisation de Google fait partie de l’API des services Google Play ( comment le configurer ). Ils sont construits sur l’API d’Android. Ces API fournissent un "fournisseur d'emplacement fusionné" au lieu des fournisseurs mentionnés ci-dessus. Ce fournisseur choisit automatiquement le fournisseur sous-jacent à utiliser, en fonction de la précision, de l'utilisation de la batterie, etc. Il est rapide car vous obtenez l'emplacement d'un service système qui le met à jour régulièrement. Et vous pouvez utiliser des fonctionnalités plus avancées telles que le geofencing.
Pour utiliser les services de localisation de Google, votre application doit se connecter au GooglePlayServicesClient
. Pour vous connecter au client, votre activité (ou fragment, ou plus) doit implémenter les interfaces GooglePlayServicesClient.ConnectionCallbacks
et GooglePlayServicesClient.OnConnectionFailedListener
. Voici un exemple de code:
public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {
LocationClient locationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
locationClient = new LocationClient(this, this, this);
}
@Override
public void onConnected(Bundle bundle) {
Location location = locationClient.getLastLocation() ;
Toast.makeText(this, "Connected to Google Play Services", Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected() {
Toast.makeText(this, "Connected from Google Play Services.", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// code to handle failed connection
// this code can be found here — http://developer.Android.com/training/location/retrieve-current.html
}
locationClient.getLastLocation()
est-il nul?La locationClient.getLastLocation()
obtient le dernier emplacement connu du client. Toutefois, le fournisseur d’emplacement fusionné ne conservera l’emplacement d’arrière-plan que si au moins un client y est connecté. Une fois le premier client connecté, il essaiera immédiatement d’obtenir un emplacement. Si votre activité est le premier client à vous connecter et que vous appelez getLastLocation()
immédiatement dans onConnected()
, le temps imparti au premier emplacement ne sera peut-être pas suffisant. Cela entraînera le location
null
.
Pour résoudre ce problème, vous devez attendre (indéterminément) que le fournisseur obtienne l’emplacement, puis appeler getLastLocation()
, ce qui est impossible à connaître. Une autre (meilleure) option consiste à implémenter l'interface com.google.Android.gms.location.LocationListener
pour recevoir des mises à jour d'emplacement périodiques (et à la désactiver dès que vous obtenez la première mise à jour).
public class MyActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
// . . . . . . . . more stuff here
LocationRequest locationRequest;
LocationClient locationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
// . . . . other initialization code
locationClient = new LocationClient(this, this, this);
locationRequest = new LocationRequest();
// Use high accuracy
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
locationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
locationRequest.setFastestInterval(FASTEST_INTERVAL);
}
// . . . . . . . . other methods
@Override
public void onConnected(Bundle bundle) {
Location location = locationClient.getLastLocation();
if (location == null)
locationClient.requestLocationUpdates(locationRequest, this);
else
Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
// . . . . . . . . other methods
@Override
public void onLocationChanged(Location location) {
locationClient.removeLocationUpdates(this);
// Use the location here!!!
}
Dans ce code, vous vérifiez si le client a déjà le dernier emplacement (dans onConnected
). Sinon, vous demandez des mises à jour d'emplacement et désactivez les demandes (dans onLocationChanged()
rappel) dès que vous recevez une mise à jour.
Notez que la locationClient.requestLocationUpdates(locationRequest, this);
doit figurer dans le rappel onConnected
, sinon vous obtiendrez un IllegalStateException
, car vous tenterez de demander des emplacements sans connexion au client Google Play Services.
Plusieurs fois, les services de localisation de l'utilisateur seraient désactivés (pour économiser la batterie ou pour des raisons de confidentialité). Dans un tel cas, le code ci-dessus demandera toujours des mises à jour d'emplacement, mais onLocationChanged
ne sera jamais appelé. Vous pouvez arrêter les demandes en vérifiant si l'utilisateur a désactivé les services de localisation.
Si votre application nécessite d’activer les services de localisation, vous souhaitez afficher un message ou un toast. Malheureusement, il n’existe aucun moyen de vérifier si l’utilisateur a désactivé les services de localisation dans l’API des services de localisation de Google. Pour cela, vous devrez recourir à l’API d’Android.
Dans votre méthode onCreate
:
LocationManager manager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationEnabled = false;
Toast.makeText(getActivity(), "Enable location services for accurate data", Toast.LENGTH_SHORT).show();
}
else locationEnabled = true;
Et utilisez le drapeau locationEnabled
dans votre méthode onConnected
comme ceci:
if (location != null) {
Toast.makeText(getActivity(), "Location: " + location.getLatitude() + ", " + location.getLongitude(), Toast.LENGTH_SHORT).show();
}
else if (location == null && locationEnabled) {
locationClient.requestLocationUpdates(locationRequest, this);
}
merci à Rahul Jiresal
UPDATE
Le document est mis à jour, LocationClient est supprimé et l’API prend en charge l’activation du GPS en un clic depuis la boîte de dialogue:
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
}
});
task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sendEx) {
// Ignore the error.
}
}
}
});
Lien https://developer.Android.com/training/location/change-location-settings#Prompt
Nouveau client d'emplacement: FusedLocationProviderClient
private FusedLocationProviderClient fusedLocationClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
}
Il est recommandé de passer https://developer.Android.com/training/location avant de commencer toute tâche de localisation.
D'après mon expérience, "exactitude plus appropriée" ne signifie en aucun cas mieux. Sauf si quelque chose me manque, si vous voulez vous assurer que le GPS est utilisé, LocationManager est la seule solution. Nous suivons les véhicules avec notre application et, encore une fois, à moins que quelque chose ne me manque, les services Google Play fournissent assez souvent des lieux très inexacts.
Vous devez utiliser l’API de localisation des services Google Play au lieu de LocationManager. Selon les docs:
Les API de localisation des services Google Play sont privilégiées par rapport aux Android API de localisation (Android.location) comme moyen de renforcer la reconnaissance de la localisation de votre application. Si vous utilisez actuellement les API d'emplacement du cadre Android, nous vous encourageons vivement à basculer sur les API d'emplacement des services Google Play dès que possible.
Quant à savoir pourquoi changer, Google dit ceci:
L'API des services de localisation de Google, qui fait partie des services Google Play, fournit un cadre de haut niveau plus puissant qui gère automatiquement les fournisseurs de localisation, les déplacements des utilisateurs et la précision de la localisation. Il gère également la planification des mises à jour d'emplacement en fonction des paramètres de consommation d'énergie fournis. Dans la plupart des cas, vous obtiendrez de meilleures performances de la batterie, ainsi qu'une précision plus appropriée, en utilisant l'API Services de localisation.
J'utilise l'API Google Location Services depuis un certain temps. Il présente des avantages car il présente la complexité de disposer de plusieurs sources pour déterminer les positions. Cependant, il encapsule trop fortement , de sorte que lorsque vous obtenez une position étrange, vous n’avez aucun moyen de déterminer l’origine de cette position.
Dans la vie réelle, plusieurs valeurs étranges sont apparues, à 10 kilomètres de la position réelle. La seule explication est que ces emplacements loufoques proviennent d'erreurs dans les bases de données Wi-Fi ou NWK de Googles - erreurs qui resteront toujours d'actualité, car les topologies Wi-Fi et réseau changent chaque jour. Mais malheureusement (et étonnamment), l’API ne vous donne aucune information sur la façon dont une position individuelle a été dérivée.
Cela vous laisse avec les problèmes de filtrer les valeurs anormales basées sur le contrôle de vraisemblance de la vitesse, l'accélération, le relèvement, etc.
... ou revenez à la bonne vieille API de framework et utilisez uniquement le GPS, ce que j'ai décidé de faire jusqu'à ce que Google améliore l'API fusionnée.
L'API des services de localisation de Google , qui fait partie des services de Google Play, fournit des cadre qui gère automatiquement les fournisseurs d’emplacement , le mouvement des utilisateurs et la précision de l’emplacement . Il gère également la planification des mises à jour d'emplacement en fonction des paramètres de consommation d'énergie fournis. Dans la plupart des cas, vous obtiendrez de meilleures performances de la batterie , ainsi qu'une précision plus appropriée, par en utilisant l'API Services de localisation.
Différences plus détaillées entre les deux apis API Google Play Service Service et API Android Framework Location peut être trouvé ici
Oui, l'API Services de localisation des services Google Play peut donner des informations de localisation très trompeuses. Les modems WiFi sont déplacés, les modems WiFi sont mis à jour avec des informations de localisation incorrectes (c'est-à-dire si la localisation est falsifiée par un périphérique Android qui met à jour la position du modem WiFi) et qu'il existe de nombreuses autres circonstances susceptibles de générer des données de localisation incorrectes. Triangulation modem WiFi. Dans toutes nos applications où la localisation précise est obligatoire, nous utilisons uniquement le GPS.
Différences entre les deux apis API Google Play Service Location et Android API Framework Location basée sur service GPS
FusedLocationProviderClient
requestLocationUpdates()
pour extraire l'emplacement.locationRequest.setInterval(milliseconds)
et setFastestInterval(milliseconds)
, pas sur changement de localisation de l'utilisateurLocationManager Api
La localisation récupérée en fonction de l'utilisateur changement d'emplacement et intervalles de tempslocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, milliseconds, mindistance, Mylocationlistener)
La valeur LatLng renvoyée contient (14 valeurs décimales(par exemple: 11.94574594963342 79.81166719458997))valeurs de localisation précises
Comme indiqué dans la documentation officielle , cette classe vous permet d'utiliser les services pour un emplacement, de mettre à jour périodiquement la position géographique de l'appareil ou d'envoyer "Intent" à des applications, afin de dire que l'appareil est près de l'emplacement prédéterminé. L'API nécessite ACCESS_COARSE_LOCATION
ou ACCESS_FINE_LOCATION
Il est totalement incompatible avec LocationManager, mais en ce qui concerne le fonctionnement en temps réel, il existe certaines différences fondamentales.
En ce qui concerne les services Google Location API, comparés à LocationManager, nous avons constaté une augmentation significative des performances et de la stabilité lors de l’utilisation. Par exemple, il y avait un problème courant avec LocationManager qui recevait des emplacements précédents ou des mises à jour de carte, lorsque des paramètres avaient été définis pour la période minimale et la distance minimale à partir desquelles le périphérique devait être déplacé pour les mises à jour ultérieures; l'un des paramètres était généralement ignoré. Dans les services API Google Location, ce problème n'a pas été rencontré. En outre, les services de localisation de Google consomment moins de poudre de batterie.
En conséquence, les services Google Location API ont obtenu de meilleurs résultats dans tous les cas. Cependant, il y a aussi quelques inconvénients. Pour utiliser les services de localisation, vous devez installer les services Google Play.
Par conséquent, l'application ne fonctionnera pas sur les appareils dotés d'un micrologiciel habituel non pris en charge par Google ou sur lesquels Google Services n'est pas disponible. C'est un point très important qu'il faut prendre en compte. Les recherches dans ce domaine ont révélé le fait que la plupart des utilisateurs ne disposent pas des services Google Play. Par exemple, ils ne sont pas disponibles en Chine en raison de la politique nationale, et il s’agit d’une partie importante du marché qui ne peut être ignorée. Dans ce cas, il est nécessaire de se tourner vers LocationManager.
Les services API Google Location sont la meilleure solution pour utiliser des cartes. Cette API vous permet de travailler avec les coordonnées les plus précises et avec des dépenses minimales en termes de ressources mobiles, tant que l'utilisateur a installé les services Google Play. sinon, la seule solution est LocationManager.
Lire la suite ici