LocationListener
Pour pouvoir géocaliser un utilisateur, il faut que vous possédiez une instance de la classe LocationListener ou que l’activité incluant votre carte implémente l’interface LocationListener. Nous allons opter pour la seconde solution et faire en sorte que la classe HelloGoogleMapActivity implémenter cette interface.Ainsi afin de pouvoir s’abonner à la mise à jour des coordonnées de l’utilisateur, il faut utiliser la méthode requestLocationUpdates(String, long, float, LocationListener).
Cette méthode posséde 4 arguments :
- Le provider utiliser pour recevoir les mises à jour des coordonnées utilisateurs (GPS / NETWORK …)
- Un interval minimum entre deux notifications (en millisecondes)
- Un interval minimum entre deux notifications (en metre)
- L’instance de votre LocationListener
Ce qui donnera :
@Override protected void onResume() { super.onResume(); lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, this); } @Override protected void onPause() { super.onPause(); lm.removeUpdates(this); }Implémenter l’interface LocationListener équivaut à surchager les 4 méthodes suivantes :
- OnProviderEnabled(String provider) : Cette méthode est appelée quand une source de localisation est activée (GPS, 3G..etc). L’argument représente le nom de la source activée. Vous pouvez par exemple vous abonner à la mise à jour de localisation via cette source. Ce qui donnera :
@Override public void onProviderEnabled(String provider) { String msg = String.format(getResources().getString(R.string.provider_enabled), provider); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }avec
<string name="provider_enabled">The provider %s is now enabled</string>
@Override public void onProviderDisabled(String provider) { String msg = String.format(getResources().getString(R.string.provider_disabled), provider); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }avec
<string name="provider_disabled">The provider %s is now disabled</string>
@Override public void onStatusChanged(String provider, int status, Bundle extras) { String newStatus = ""; switch (status) { case LocationProvider.OUT_OF_SERVICE: newStatus = "OUT_OF_SERVICE"; break; case LocationProvider.TEMPORARILY_UNAVAILABLE: newStatus = "TEMPORARILY_UNAVAILABLE"; break; case LocationProvider.AVAILABLE: newStatus = "AVAILABLE"; break; } String msg = String.format(getResources().getString(R.string.provider_disabled), provider, newStatus); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }avec
<string name="provider_new_status">The provider %1$s has now a new status %2$s</string>
@Override public void onLocationChanged(Location location) { latitude = location.getLatitude(); longitude = location.getLongitude(); altitude = location.getAltitude(); accuracy = location.getAccuracy(); String msg = String.format( getResources().getString(R.string.new_location), latitude, longitude, altitude, accuracy); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); }avec
<string name="new_location">New Location : Latitude = %1$s, Longitude = %2$s, Altitude = %3$s avec une précision de %4$s mètres </string>Ce qui donne pour la classe complète :
package com.android.map; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.view.KeyEvent; import android.view.Menu; import android.widget.Toast; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; public class HelloGoogleMapActivity extends MapActivity implements LocationListener { private MapView mapView; private MapController mc; private LocationManager lm; private double latitude; private double longitude; private double altitude; private float accuracy; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mapView = (MapView) this.findViewById(R.id.mapView); mapView.setBuiltInZoomControls(true); mc = mapView.getController(); mc.setZoom(17); } @Override protected void onResume() { super.onResume(); lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, this); } @Override protected void onPause() { super.onPause(); lm.removeUpdates(this); } @Override protected boolean isRouteDisplayed() { return false; } @Override public void onLocationChanged(Location location) { latitude = location.getLatitude(); longitude = location.getLongitude(); altitude = location.getAltitude(); accuracy = location.getAccuracy(); String msg = String.format( getResources().getString(R.string.new_location), latitude, longitude, altitude, accuracy); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); } @Override public void onProviderDisabled(String provider) { String msg = String.format( getResources().getString(R.string.provider_disabled), provider); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } @Override public void onProviderEnabled(String provider) { String msg = String.format( getResources().getString(R.string.provider_enabled), provider); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { String newStatus = ""; switch (status) { case LocationProvider.OUT_OF_SERVICE: newStatus = "OUT_OF_SERVICE"; break; case LocationProvider.TEMPORARILY_UNAVAILABLE: newStatus = "TEMPORARILY_UNAVAILABLE"; break; case LocationProvider.AVAILABLE: newStatus = "AVAILABLE"; break; } String msg = String.format( getResources().getString(R.string.provider_disabled), provider, newStatus); Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } }Petite explications :
- Nous avons besoin d’une instance de la classe LocationManager. Cette dernière donne accès au service de localisation. Cela permet aux applications d’obtenir des mises à jour périodiques de la position de l’utilisateur.
- On appele la méthode requestLocationUpdate pour la mise à jour via le Réseau (NetWork) et le GPS.
- On implémente les méthodes obligatoires de LocationListener.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- INTERNET : Pour télécharger et afficher les cartes
- ACCESS_FINE_LOCATION : Pour pouvoir localiser précisément l’utilisateur (GPS)
- ACCESS_COARSE_LOCATION : Pour pouvoir localiser approximativement l’utilisateur (WIFI, 3G..)
Mise à jour de la position sur la carte
Maintenant que les nouvelles coordonnées de l’utilisateur sont récupérées, on aimerait mettre à jour la carte afin qu’elle se positionne à l’emplacement de l’utilisateur. Pour cela, il faut créer une instance de la classe GeoPoint (Représentant un point sur un carte) à l’aide des nouvelles coordonnées, puis demander à la carte de se déplacer à cette position. Ce qui donnera :@Override public void onLocationChanged(Location location) { latitude = location.getLatitude(); longitude = location.getLongitude(); altitude = location.getAltitude(); accuracy = location.getAccuracy(); String msg = String.format( getResources().getString(R.string.new_location), latitude, longitude, altitude, accuracy); Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); GeoPoint p = new GeoPoint((int) (latitude * 1E6), (int) (longitude * 1E6)); mc.animateTo(p); mc.setCenter(p); }Voici le résultat de cet exemple :
Pour pouvoir mettre à jour les coordonnées de l’utilisateur à l’aide d’un émulateur, deux solutions sont disponibles :
- l’émulateur contrôle : Fourni avec le SDK et intégré à Eclipse.
- Un client telnet (PuttyTel) : Pour l’utiliser, il suffit de le lancer et remplir les champs suivants (Host Name : localhost et Port 5554) et pour finir taper help pour connaître les différentes commandes. En ce qui concerne la géolocalisation la commande est la suivante : geo fix latitude longitude.