OpenStreetMap en Android Studio
Por amunoz el Martes, 29 de Marzo de 2016, 14:40 - Enlace permanente
EDITADO 23/05/2017: actualizado a la última versión de Osmdroid.
EDITADO 03/08/2017: añadida comprobación de permisos en el proyecto de ejemplo para Android 6>.
EDITADO 07/08/2017: Actualizaciones de ubicaciones (proyecto de ejemplo).
Tener mapas en nuestra aplicación android es muy fácil con Android Studio ya que no hacen falta registros, cuentas, tokens o API Keys. Veremos que es muy sencillo con Android Studio.
Vamos a crear un proyecto de ejemplo para que de más claro. Por lo tanto el primer paso es crear el proyecto.
Android Studio proporciona un asistente muy fácil de seguir, le ponemos un nombre al proyecto, seleccionamos los dispositivos destinatarios de la aplicación, en este caso sólo marcaremos "Phone and Tablet" y por ejemplo la API 17 (versión 4.2), aunque podéis seleccionar otra. Después seleccionamos una actividad en blanco y finalizamos el asistente.
Una vez con el proyecto base creado tenemos que añadir a las dependencias del proyecto la librería osmdroid, esto lo hacemos editando el fichero build.gradle (app) y dentro de dependencies {} añadimos la siguiente línea:
compile 'org.osmdroid:osmdroid-android:5.6.4'
Una vez hecho esto, sincronizamos el proyecto y esperamos a que termine.
Ahora tenemos que añadirle permisos para poder obtener los mapas de Internet, por lo tanto añadiremos en nuestro fichero manifest.xml (por encima del tag application) las siguientes líneas:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Ahora añadiremos en la vista de nuestra actividad la View donde se mostrará el mapa, abrimos el correspondiente layout y añadimos dentro de un LinearLayout:
<org.osmdroid.views.MapView android:id="@+id/openmapview" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
Y por último modificamos nuestro código Java para que quede como en la siguiente captura:
Ya estamos listos para ejecutar la aplicación y probarla, si todo va bien veremos el siguiente resultado:
Podemos marcar nuestra posición actual y centrar el mapa en ella, para ello tenemos disponible una capa llamada MyLocationNewOverlay que añadiremos (o no) al mapa y moveremos el mapa a nuestra posición actual mediante el método runOnFirstFix, ya que si lo hacemos directamente causaremos un NullPointerException:
final MyLocationNewOverlay myLocationoverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(getApplicationContext()), myOpenMapView); myOpenMapView.getOverlays().add(myLocationoverlay); //No añadir si no quieres una marca myLocationoverlay.enableMyLocation(); myLocationoverlay.runOnFirstFix(new Runnable() { public void run() { myMapController.animateTo(myLocationoverlay.getMyLocation()); } });
Podemos añadir marcas en puntos específicos creando una lista de puntos con una serie de atributos y creando una capa nueva que contenga esa información. Además, si añadimos un OnItemGestureListener podremos interactuar con los puntos añadidos y crear globos mediante la función setFocusItemsOnTap:
ArrayList<OverlayItem> puntos = new ArrayList<OverlayItem>(); puntos.add(new OverlayItem("Madrid", "Ciudad de Madrid", madrid)); ItemizedIconOverlay.OnItemGestureListener<OverlayItem> tap = new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() { @Override public boolean onItemLongPress(int arg0, OverlayItem arg1) { return false; } @Override public boolean onItemSingleTapUp(int index, OverlayItem item) { return true; } }; ItemizedOverlayWithFocus<OverlayItem> capa = new ItemizedOverlayWithFocus<OverlayItem>(this, puntos, tap); capa.setFocusItemsOnTap(true); myOpenMapView.getOverlays().add(capa);
Y tendremos como resultado nuestra marca y globo informativo:
Adjunto el proyecto de ejemplo.
Saludos!
Comentarios
Excelente ayuda. Solo me resta preguntarte como hago si quiero usar un mapa offline con OSM. Muchas gracias desde ya.
Dos preguntas......
1 Por alguna razón no me carga el mapa (esta igual a tu ejemplo ).
2.Donde agrego lo de "MyLocationNewOverlay "
Otra ves..... punto 2 solucionado
pero sigue sin mostrarme l mapa
Hola Michael,
He actualizado la entrada y adjunto un proyecto de ejemplo.
Creo que tu problema era el contenedor de la view del mapa, por defecto Android añade un layout de tipo ConstraintLayout y no basta con añadir la view del mapa. Cambiando ConstraintLayout por LinearLayout debe mostrarse.
Saludos!
Hola José,
Puede que haga una entrada con ese tema, pero mientras podrías echarle un vistazo a la documentación oficial:
https://github.com/osmdroid/osmdroid/wiki/Offline-Map-Tiles
Saludos
Buenas tardes,
He realizado los mismos pasos y me sale el mapa vacío...
He descargado tu proyecto de ejemplo y me sale igual, ¿que puede ser?
Gracias.
Saludos!
Hola Lucía,
OpenStreepMap guarda las imágenes de los mapas en el almacenamiento externo y a partir de la versión 6 de Android hay que preguntar por los permisos de escritura antes de cargar el mapa.
He actualizado el proyecto de ejemplo con este cambio, podrás ver que he puesto todo lo referente al mapa en un procedimiento en lugar de en el onCreate.
Un saludo!
Gracias amunoz!
Me funciona correctamente. Solo me queda, en este código me muestra el muñeco en la ubicación actual, pero estoy intentando guardar los puntos geográficos(geopoint con latitud y longitud) de ese mismo punto y estoy teniendo problemas, ¿alguna idea?
Saludos!
Hola,
Lo que te aparece en el mapa es la última posición conocida que proporciona el sistema. Para obtener los cambios de ubicación hace falta crear un listener que le pasaremos al LocationManager del sistema. Este listener irá actualizando el mapa con la nueva ubicación.
Actualizo el proyecto de ejemplo por si te sirve. También te recomiendo la lectura de este tutorial (tiene dos partes): http://www.sgoliver.net/blog/locali...
Saludos
encontré un error por si acaso les sucede en la siguiente linea:
final MyLocationNewOverlay myLocationoverlay = new MyLocationNewOverlay (getApplicationContext(), new GpsMyLocationProvider(getApplicationContext()), myOpenMapView);
Disculpa ya realice todos los pasos y creo estan correctos y tambien me sale la etiqueta con el nombre de la ubicación pero no se cual sea el problema que solo me sale una una cuadricula en lugar del mapa en mi telefono.¿alguna idea de cual pueda ser el problema?
Hola 10DIEZ,
Habilita los permisos de almacenamiento y ubicación para la aplicación. Seguramente sea eso.
OpenStreepMap cachea las imágenes del mapa en una carpeta llamada "osmdroid", si no puede escribir no muestra nada.
Saludos!
Excelente ya quedo, muchas gracias. Oye una pregunta de casualidad sabes si existe la posibilidad de cambiar el mapa a otro que sea de satélite igual en Open Street Maps?
Hola, gran tutorial, sé pedir una ayuda. ¿Cómo puedo insertar una nueva marca sin necesidad de implementar dentro del sistema? Utilizando el mismo recurso de notas del mapa de calles abierto?
Hola !
Implemente la guia pero sigue sin aparecer el mapa.
Le doy los permisos de escritura de forma manual y sigue sin funcionar.
No se si a alguien mas le paso?
Saludos
Hola, que pasa si no se cuenta con almacenamiento externo. La app funcionará?
Hay alguna alternativa para que se guarde en almacenamiento interno?
Gracias.
Saludos.
para los que "NO LES APARECE EL MAPA" es la version #implementation 'org.osmdroid:osmdroid-android:6.1.0'#