Guide du développeur Android pour l'API Google Location Services

Publié: 2022-03-11

Connaître l'emplacement de votre utilisateur est une information utile dans de nombreuses applications que nous développons et utilisons aujourd'hui. Il existe de nombreuses applications populaires basées sur la localisation qui nous facilitent la vie et changent la façon dont nous utilisons ces services. Un exemple est l'application très populaire Foursquare, où les utilisateurs qui fréquentent un établissement et « s'enregistrent » gagnent souvent des réductions. Uber, qui vous aide à vous déplacer depuis votre téléphone portable à un tarif inférieur à celui d'un taxi normal. La liste est longue et ne cesse de s'allonger.

API des services de localisation

Dans cet article, nous allons créer une application Android simple pour déterminer la latitude et la longitude de l'utilisateur à l'aide de l'API Google Location Services d'Android. Lors du développement d'applications Android, il existe plusieurs façons d'obtenir la position de l'utilisateur.

Paquet "android.location"

Le package "android.location" est disponible depuis l'introduction d'Android et nous donne accès aux services de localisation. Ces services permettent aux applications d'obtenir des mises à jour périodiques de l'emplacement géographique de l'appareil.

Le package fournit deux moyens d'acquérir des données de localisation :

  • LocationManager.GPS_PROVIDER : détermine l'emplacement à l'aide de satellites. Selon les conditions, ce fournisseur peut prendre un certain temps pour renvoyer une position fixe.

  • LocationManager.NETWORK_PROVIDER : détermine l'emplacement en fonction de la disponibilité des antennes relais et des points d'accès WiFi à proximité. C'est plus rapide que GPS_PROVIDER.

Lorsque vous recherchez l'emplacement de l'utilisateur, vous devez jouer avec ces fournisseurs et leur disponibilité. Idéalement, vous obtenez le premier emplacement à l'aide de NETWORK_PROVIDER, qui n'est peut-être pas aussi précis, mais qui est beaucoup plus rapide. Vous pouvez alors tenter d'augmenter la précision en écoutant un meilleur emplacement à l'aide de GPS_PROVIDER.

Les API fournies par ce package sont de niveau assez bas et nécessitent que le développeur de l'application gère les détails les plus fins pour déterminer quand demander les données de localisation et planifier les appels à l'API de manière optimisée. Pour améliorer l'expérience des développeurs avec les services système basés sur la localisation et faciliter le processus de développement d'applications sensibles à la localisation, Google a introduit une nouvelle façon de demander l'emplacement d'un utilisateur à l'aide des services Google Play. Il offre une API plus simple avec une plus grande précision, un géorepérage à faible consommation d'énergie et bien plus encore.

API des services de localisation Google

L'API Google Location Services, également connue sous le nom de FusedLocationProviderApi, est la méthode recommandée par Google pour obtenir la position d'un utilisateur. Il fournit la meilleure précision en fonction de nos besoins. Certains des avantages de l'utilisation de cette API par rapport à la précédente sont :

  • Simplicité : contrairement à l'API précédente, vous n'avez plus à traiter avec plusieurs fournisseurs. Au lieu de cela, vous spécifiez des besoins de haut niveau, tels que "haute précision" ou "faible puissance", et il adoptera une approche appropriée.

  • Disponibilité : donne à votre application un accès immédiat au meilleur emplacement connu le plus récent. Habituellement, cette information est facilement disponible, il vous suffit de la demander.

  • Efficacité énergétique : minimise la consommation d'énergie de votre application.

  • Polyvalence : Répond à un large éventail de besoins, des utilisations de premier plan - nécessitant des données de localisation très précises, aux utilisations en arrière-plan - ne nécessitant que des mises à jour de localisation périodiques avec un impact énergétique négligeable.

Construisons une application Android basée sur la localisation à l'aide de cette API. Pour cela, nous utiliserons l'IDE suggéré par Google pour le développement d'applications Android - Android Studio. Démarrer avec Android Studio est assez simple. Leur site Web décrit en détail la procédure d'installation et de configuration d'Android Studio, y compris comment démarrer votre première application Android pour le développement.

Android Studio devrait nous faciliter la tâche. Cependant, nous devrons commencer par configurer le script de construction et ajouter les services Google Play en tant que dépendance pour cette application. Cela peut être fait en modifiant le fichier "build.gradle" comme suit :

 dependencies { compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.google.android.gms:play-services:6.5.87' // Add this line }

Au moment où j'écris cet article, la dernière version disponible des services Google Play est la 6.5.87. Assurez-vous de toujours vérifier la dernière version disponible avant de commencer. Si de nouvelles versions sortent plus tard et que vous décidez de les mettre à jour pour vos propres projets, testez toutes les fonctionnalités liées à la localisation par rapport à toutes les versions d'Android que vous prenez en charge.

À ce stade, nous devrions être en mesure de commencer à faire le travail proprement dit pour notre application.

Demande d'autorisation, configuration d'AndroidManifest.xml

Les androïdes ont des fonctionnalités de sécurité spécifiques qui empêcheraient toute application arbitraire de demander un emplacement utilisateur précis. Pour résoudre ce problème, nous devons modifier "AndroidManifest.xml" et ajouter l'autorisation dont nous avons besoin pour cette application :

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Pendant que nous y sommes, nous devons également définir la version des services Google Play que nous utilisons pour cette application :

 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

Vérification de la disponibilité des services Google Play

Avant d'accéder aux fonctionnalités fournies par les services Google Play, nous devons vérifier si l'appareil dispose des services Google Play et que la version est celle que nous avons l'intention d'utiliser (6.5.87).

 private boolean checkGooglePlayServices(){ int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * Google Play Services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mContext, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; }

Cette méthode vérifiera les services Google Play, et au cas où l'appareil ne l'aurait pas installé (c'est rare, mais j'ai vu de tels cas), il ouvrira une boîte de dialogue avec l'erreur correspondante et invitera l'utilisateur à installer/mettre à jour Services Google Play du Google Play Store.

Services de jeu Google

Une fois que l'utilisateur a terminé la résolution fournie par "GooglePlayServicesUtil.getErrorDialog()", une méthode de rappel "onActivityResult()" est déclenchée, nous devons donc implémenter une logique pour gérer cet appel :

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(mContext, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } }

Accéder aux API Google

Pour accéder aux API Google, il suffit d'effectuer une étape supplémentaire : créer une instance de GoogleApiClient. Le client API Google fournit un point d'entrée commun à tous les services Google Play et gère la connexion réseau entre l'appareil de l'utilisateur et chaque service Google. Notre première étape consiste à initier la connexion. J'appelle généralement ce code à partir de la méthode "onCreate" de l'activité :

 protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); }

En enchaînant une série d'appels de méthode, nous spécifions l'implémentation de l'interface de rappel et l'API du service de localisation que nous voulons utiliser. L'implémentation de l'interface, dans ce cas "ceci", recevra une réponse à la méthode asynchrone "connect()" lorsque la connexion aux services Google Play réussit, échoue ou est suspendue. Après avoir ajouté ce code, notre « MainActivity » devrait ressembler à ceci :

 package com.bitwoo.userlocation; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkGooglePlayServices()) { buildGoogleApiClient(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkGooglePlayServices() { int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } }

Ensuite, dans notre méthode "onStart", nous appelons la méthode "connect" et attendons que la méthode de rappel "onConnected" soit invoquée :

 @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }

La méthode "onConnected" ressemblera à ceci :

 @Override public void onConnected(Bundle bundle) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }

Ce rappel est déclenché lorsque les services Google Play sont connectés, ce qui signifie que nous devrions alors avoir le dernier emplacement connu. Cependant, cet emplacement peut être nul (c'est rare mais pas impossible). Dans ce cas, ce que je recommande est d'écouter les mises à jour de localisation qui seront couvertes ensuite.

Écoute des mises à jour de localisation

Après avoir appelé "getLastLocation", vous souhaiterez peut-être demander des mises à jour périodiques au fournisseur d'emplacement fusionné. Selon votre application, cette période peut être courte ou longue. Par exemple, si vous construisez une application qui suit l'emplacement d'un utilisateur pendant qu'il conduit, vous devrez écouter les mises à jour à de courts intervalles. D'un autre côté, si votre application concerne le partage de l'emplacement de l'utilisateur avec son ami, vous n'aurez peut-être qu'à demander l'emplacement de temps en temps.

La création d'une requête est assez simple - vous pouvez appeler cette méthode dans la méthode "onCreate" :

 protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(20000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }

Nous instancions un nouvel objet LocationRequest. Définissez l'intervalle sur 20 secondes (20 000 millisecondes). De plus, nous avons défini un taux de mise à jour limité à 5 secondes. Cela indique à l'API de fournir des mises à jour toutes les 20 secondes (de préférence), mais si un changement est disponible dans un délai de 5 secondes, il devrait également le fournir. Enfin, nous définissons la priorité sur "PRIORITY_HIGH_ACCURACY", parmi les autres options de priorité disponibles : PRIORITY_BALANCED_POWER_ACCURACY, PRIORITY_LOW_POWER, PRIORITY_NO_POWER.

Une fois que vous avez créé la requête, vous êtes prêt à commencer à écouter les mises à jour de localisation après le déclenchement de la méthode "onConnected()" :

 protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); }

Il ne reste plus qu'à implémenter la méthode callback pour satisfaire l'interface LocationListener :

 public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // ... @Override public void onLocationChanged(Location location) { mLastLocation = location; Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } } 

arrêter d'écouter les mises à jour

Arrêtez d'écouter les mises à jour

Il est important d'arrêter explicitement d'écouter les mises à jour lorsque vous n'en avez plus besoin ou si l'utilisateur quitte votre application. La méthode suivante doit être invoquée depuis le rappel "onPause" :

 protected void stopLocationUpdates() { if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } }

… et déconnexion de l'API Google :

 @Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } }

Emballer

Comme vous pouvez le voir, les idées fondamentales derrière la mise en œuvre d'applications sensibles à la localisation dans Android sont très simples. De plus, avec les API disponibles qui sont à la fois simples à utiliser et faciles à comprendre, il devrait être facile de créer des applications de base basées sur la localisation pour Android. Le petit exemple d'application que nous avons construit ici est destiné à démontrer exactement cela. Vous pouvez trouver le code source complet pour cela sur GitHub. Veuillez noter que pour simplifier les choses, l'application ne gère pas la méthode de rappel "onConnectionFailed".

J'espère que ce didacticiel vous aidera à démarrer avec l'API Google Location Services.