Curso Android: Geolocalización y utilización de mapas de Google
En el quinto capítulo del Curso Android seguiremos trabajando con el hardware de los teléfonos, ahora nos corresponde aprovechar el GPS y mostrar la ubicación actual en un mapa. La aplicación que realizaremos nos permitirá mostrar la ubicación y actualizarse cada vez que exista movimiento.
Es importante notar que las pruebas de este capítulo al igual que los capítulos 4 y 5 son para realizarlas en un teléfono con Android es posible utilizar el emulador con algunos arreglos. Ejemplo: obtener localización, monitorear sus cambios y mostrarla en un mapa a través de markers. Queremos que al finalizar se vea de la siguiente form:
Disposición inicial
Iniciamos descargando el código que debe ser importado hacia un nuevo proyecto y que tiene algunas características importantes.
- Permisos en el Manifest, por el acceso a internet para el mapa y la ubicación del GPS requerimos estos 2 permisos bajo el tag:12
<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/> - Uso de la librería de mapas, también en el Manifest bajo el tag:1
- En la clase de la actividad principal, utilizaremos herencia de
MapActivitypara facilitarnos el manejo del mapa e implementaremos la interfazLocationListenerpara detectar los cambios en la localización. - Por heredar de
MapActivitydebemos implementar el método:1234@OverrideprotectedbooleanisRouteDisplayed() {returnfalse;} - Por implementar LocationListener debemos realizar los siguientes métodos:0102030405060708091011
@OverridepublicvoidonLocationChanged(Location location) {}@OverridepublicvoidonProviderDisabled(String provider) {}@OverridepublicvoidonStatusChanged(String provider,intstatus, Bundle extras) {}@OverridepublicvoidonProviderEnabled(String provider) {}
Diseño
Utilizaremos una vista especial para el mapa es necesario un key para la utilización del servicio de Google Maps y depende directamente del certificado utilizado para firmar las aplicaciones, el valor del atributo android:apiKey que aparece en el código es válida para mi certificado.
1 2 3 4 5 6 7 8 | <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="0xJ4uwRGDV296srCn4Iiy46oFmd1jecLr07BsAA"/> |
Agregando código
La clase de la Activity para nuestra aplicación extenderá de MapActivity para facilitarnos el manejo de la visualización del mapa e implementará LocationListener para el manejo de las actualizaciones de ubicación.
1 | public class Main extends MapActivity implements LocationListener |
De los métodos disponibles, utilizaremos onProviderDisabled para forzar al usuario a tener el GPS funcionando antes de que la aplicación inicie.
1 2 3 4 5 | @Overridepublic void onProviderDisabled(String provider) { Intent intent = new Intent( android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent);} |
Vamos a mostrar un marker en las diferentes ubicaciones detectadas, para ello haremos una clase que represente este Overlay mostrando la imagen seleccionada. Para este ejemplo se utilizará la imagen del ícono, al definirla dentro de la misma clase de la Activity principal entonces será una clase privada.
1 | class MyOverlay extends Overlay { } |
Tendremos una variable de instancia representando el punto donde se colocará el marcador y será un parámetro recibido por el constructor:
1 2 3 4 5 6 7 | GeoPoint point;/* El constructor recibe el punto donde se dibujará el marker */public MyOverlay(GeoPoint point) { super(); this.point = point;} |
Sobrecargaremos el método draw para dibujar nuestro marker:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | @Overridepublic boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { super.draw(canvas, mapView, shadow); //se traduce el punto geo localizado a un punto en la pantalla Point scrnPoint = new Point(); mapView.getProjection().toPixels(this.point, scrnPoint); //se construye un bitmap a partir de la imagen Bitmap marker = BitmapFactory.decodeResource(getResources(), R.drawable.icon); //se dibuja la imagen del marker canvas.drawBitmap(marker, scrnPoint.x - image.getWidth() / 2, scrnPoint.y - marker.getHeight() / 2, null); return true;} |
El código completo de la clase para los overlays es el siguiente:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class MyOverlay extends Overlay { GeoPoint point; //El constructor recibe el punto donde se dibujará el marker public MyOverlay(GeoPoint point) { super(); this.point = point; }@Overridepublic boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) { super.draw(canvas, mapView, shadow); //se traduce el punto geolocalizado a un punto en la pantalla */ Point scrnPoint = new Point(); mapView.getProjection().toPixels(this.point, scrnPoint); //se construye un bitmap a partir de la imagen Bitmap marker = BitmapFactory.decodeResource(getResources(), R.drawable.icon); // se dibuja la imagen del marker canvas.drawBitmap(marker, scrnPoint.x - marker.getWidth() / 2, scrnPoint.y - marker.getHeight() / 2, null); return true; }} |
Para ir dibujando estos markers al principio y cada vez que haya una actualización de la ubicación, utilizaremos un método nuevo con la firma:
1 | protected void updateLocation(Location location) |
Obtenemos el MapView y de él un MapController:
1 2 | MapView mapView = (MapView) findViewById(R.id.mapview);MapController mapController = mapView.getController(); |
Construimos un punto a partir de la latitud y longitud del Location recibido:
1 | GeoPoint point = new GeoPoint((int) (location.getLatitude() * 1E6), (int) (location.getLongitude() * 1E6)); |
Movemos el centro del mapa hacia esta ubicación:
1 2 | mapController.animateTo(point);mapController.setZoom(15); |
Posterior a esto, intentaremos hacer geolocalización del punto, obtener una dirección a partir de las coordenadas del punto. Primero instanciamos un objeto Geocoder que responderá de acuerdo a la localidad configurada en el teléfono.
1 | Geocoder geoCoder = new Geocoder(this, Locale.getDefault()); |
A través de este Geocoder y con el punto de la ubicación intentamos obtener alguna dirección asociada y se lo hacemos saber al usuario por medio de un toast (aviso).
01 02 03 04 05 06 07 08 09 10 11 12 13 | try { List<Address> addresses = geoCoder.getFromLocation(point.getLatitudeE6() / 1E6, point.getLongitudeE6() / 1E6, 1); String address = ""; if (addresses.size() > 0) { for (int i = 0; i < addresses.get(0).getMaxAddressLineIndex(); i++) address += addresses.get(0).getAddressLine(i) + "\n"; } Toast.makeText(this, address, Toast.LENGTH_SHORT).show();} catch (IOException e) { e.printStackTrace();} |
Por último, instanciamos la clase MyOverlay construída previamente para agregar un nuevo marker en el listado de overlays del mapa e invalidamos la vista para que vuelva a dibujarse todo.
1 2 3 4 | List<Overlay> mapOverlays = mapView.getOverlays();MyOverlay marker = new MyOverlay(point);mapOverlays.add(marker);mapView.invalidate(); |
En el método onCreate vamos a instanciar un LocationManager para mostrar el primer marker y solicitar actualizaciones:
1 2 3 4 5 6 7 8 9 | MapView mapView = (MapView) findViewById(R.id.mapview);//habilitamos el control de zoommapView.setBuiltInZoomControls(true);LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);updateLocation(locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));/* se actualizará cada minuto y 50 metros de cambio en la localización mientras más pequeños sean estos valores más frecuentes serán las actualizaciones */locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000, 50, this); |
Luego en el método onLocationChanged llamamos a nuestro método updateLocation para que dibuje un nuevo marker cada vez que se actualice la localización:
1 2 3 4 | @Overridepublic void onLocationChanged(Location location) { updateLocation(location);} |
Descarga:
Puedes descargar el código de la aplicación completa y funcional en: Geolocalización y utilización de mapas de Google.
Conclusión
En este capítulo aprendimos sobre:
- Cómo manejar un mapa, la necesidad de una vista especial y solicitar un API Key.
- Cómo dibujar markers a través de overlays sobre el mapa, además personalizamos la imagen del marker.
- Cómo solicitar la ubicación actual y actualizaciones ante el cambio de ubicación.
El logotipo de Android es compartido por Google bajo licencia Creative Commons por Atribución.

No hay comentarios:
Publicar un comentario