Luego del post anterior donde vimos como usar google maps en nuestra aplicación vamos a integrar el GPS haciendo que nuestro mapa nos muestre “nuestra” posición.
Escuchando al GPS
AndroidManifiest.xml
Primero debemos agregar los permisos para obtener la ubicación “fina”, es decir, mediante el GPS, para esto agregamos el permiso ACCESS_FINE_LOCATION debajo del permiso que ya tenemos.
1: <uses-permission android:name="android.permission.INTERNET" />
2: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
MyGoogleMapsActivity
En la línea 16 estamos referenciando el objeto del mapa, en la 17 estamos referenciando al servicio de sistema de localización (LocationManager) y en la línea 18 estamos diciéndole al locationManager que escuche las actualizaciones del de localización producidas por el GPS con una instancia del listener MyLocationListener.
1: package com.neluz.MyGoogleMaps;
2:
3: import com.google.android.maps.MapActivity;
4: import com.google.android.maps.MapView;
5:
6: import android.content.Context;
7: import android.location.LocationManager;
8: import android.os.Bundle;
9:
10: public class MyGoogleMapsActivity extends MapActivity {
11: @Override
12: public void onCreate(Bundle savedInstanceState) {
13: super.onCreate(savedInstanceState);
14: setContentView(R.layout.main);
15:
16: MapView mapView = (MapView) findViewById(R.id.mapview);
17: LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
18: locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
19: new MyLocationListener(mapView.getController(), locationManager, getBaseContext()));
20:
21: mapView.setBuiltInZoomControls(true);
22: }
23:
24: @Override
25: protected boolean isRouteDisplayed() {
26: return false;
27: }
28: }
en la línea 21 estamos habilitando el control de zoom en el mapa, esto no es necesario para el uso de GPS, pero va mejorando nuestra aplicación.
MyLocationListener
Creamos la clase MyLocationListener implementando LocationListener y en el método onLocationChanged es donde vamos a posicionar el mapa en la nueva ubicación, para esto creamos el GeoPoint a partir de las coordenadas de la nueva localización (líneas 34 a 36) y le pedimos al controller del mapa que lo posicione en las nuevas coordenadas (línea 38). Luego hacemos zoom en esta ubicación (línea 39).
1: package com.neluz.MyGoogleMaps;
2:
3: import android.content.Context;
4: import android.location.Location;
5: import android.location.LocationListener;
6: import android.location.LocationManager;
7: import android.os.Bundle;
8: import android.widget.Toast;
9:
10: import com.google.android.maps.GeoPoint;
11: import com.google.android.maps.MapController;
12: import com.google.android.maps.MapView;
13:
14: public class MyLocationListener implements LocationListener {
15: private Context context;
16: private LocationManager locationManager;
17: private MapController mapController;
18:
19: public MyLocationListener(MapController mapController, LocationManager locationManager, Context context)
20: {
21: this.mapController = mapController;
22: this.locationManager = locationManager;
23: this.context = context;
24: }
25:
26: @Override
27: public void onLocationChanged(Location loc) {
28: Toast.makeText(context, "onLocationChanged", Toast.LENGTH_SHORT).show();
29:
30: if (loc!=null) {
31: Toast.makeText(context,
32: "Location changed : Lat: " + loc.getLatitude() + " Lng: " + loc.getLongitude(), Toast.LENGTH_SHORT).show();
33:
34: GeoPoint p = new GeoPoint(
35: (int) (loc.getLatitude() * 1E6),
36: (int) (loc.getLongitude() * 1E6));
37:
38: mapController.animateTo(p);
39: mapController.setZoom(12);
40: }
41: else
42: {
43: Toast.makeText(context, "location changed to null value", Toast.LENGTH_SHORT).show();
44: }
45:
46: // por el emulador??
47: locationManager.removeUpdates(this);
48: locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
49: new MyLocationListener(mapController, locationManager, context));
50: }
51:
52: @Override
53: public void onProviderDisabled(String arg0) {
54: Toast.makeText(context, "Provider Disabled",
55: Toast.LENGTH_SHORT).show();
56: }
57:
58: @Override
59: public void onProviderEnabled(String arg0) {
60: Toast.makeText(context, "Provider Enabled",
61: Toast.LENGTH_SHORT).show();
62:
63:
64: }
65:
66: @Override
67: public void onStatusChanged(String provider, int status, Bundle arg2) {
68: Toast.makeText(context, "Status on " + provider + " is " + getStatusMessage(status),
69: Toast.LENGTH_SHORT).show();
70: }
71:
72: private String getStatusMessage(int status) {
73: // TODO Auto-generated method stub
74: if (status == 1)
75: return "contecting";
76: else if (status == 2)
77: return "conected";
78: return "unknown";
79: }
80:
81: }
las líneas 47 a 49 no estoy seguro que sean necesarias, pero el emulador de posiciones no funciona sino reiniciamos el listener.
Simulando posiciones
Algo que probablemente queramos hacer es simular distintas posiciones de nuestro Android como si estuviésemos en esos lugares (o moviéndonos). Para esto me encontré con una limitación que les cuento a continuación y dos alternativas para solucionarlo.
Una limitación y dos solución
Una gran “limitación” en el “Emulator Console” ya sea el integrado con Eclipse como el que se ejecuta desde DDMS es que requieren que la configuración regional esté en formato inglés de estados unidos. Así que o bien cambian la configuración regional de sus PCs o bien usan la terminal telnet, yo me quedé con esta segunda opción (aunque probé y ambas funcionan).
Si ustedes desarrollan todo como está en este post y al enviarle coordenadas al Android, el gps cambia de estado pero nunca se ejecuta el evento onLocationChanged es por este problema.
Simulando posiciones con telnet
Ejecutamos el comando telnet localhost 5554, donde 5554 es el puerto del AVD (Android Virtual Devices) donde están emulando el Android. Luego, con el comando geo fix simulamos datos del GPS.
ejecutamos el comando: geo fix -58.433533 -34.615127 |
Nuestra aplicación debe navegar hasta esta ubicación, en la ciudad de Buenos Aires. |
Luego podemos ir a:
-
geo fix –69.18 –16.01 (Isla del Sol en Bolivia)
-
geo fix –3.59 37.18 (Granada en España)
-
y todo un planeta para navegar