1. Bienvenido
Este codelab es parte del curso de capacitación sobre desarrollo avanzado de Android, desarrollado por el equipo de capacitación de Google Developers. Aprovecharás al máximo este curso si trabajas con los codelabs en secuencia.
Para obtener información completa sobre el curso, consulta la Descripción general del desarrollo avanzado de Android.
Introducción
Crear apps con Google Maps te permite agregar funciones a tu app, como imágenes satelitales, controles de IU sólidos, seguimiento de ubicación y marcadores de ubicación. Puedes agregar valor a Google Maps estándar mostrando información de tu propio conjunto de datos, como las ubicaciones de áreas de pesca o escalada conocidas. También puedes crear juegos vinculados al mundo real, como Pokémon Go.
En esta práctica, crearás una app de Google Maps llamada Wander
.
Conocimientos que ya deberías tener
Debes estar familiarizado con lo siguiente:
- Funcionalidad básica de Google Maps
- Permisos de tiempo de ejecución.
- Creación, compilación y ejecución de apps en Android Studio
- Incluir bibliotecas externas en el archivo
build.gradle
.
Qué aprenderás
- Integra un mapa de Google Maps en tu app.
- Muestra diferentes tipos de mapas.
- Aplica diseño al mapa de Google Maps.
- Agrega marcadores a tu mapa.
- Permite que el usuario coloque un marcador en un lugar de interés.
- Habilita el seguimiento de la ubicación.
- Habilita Google Street View.
Actividades
- Obtén una clave de API en la Consola de APIs de Google y regístrala en tu app.
- Crea la app de
Wander
, que tiene un mapa de Google incorporado. - Agrega funciones personalizadas a tu app, como marcadores, estilos y seguimiento de ubicación.
- Habilita el seguimiento de ubicación y Street View en tu app.
2. Descripción general de la app
En esta práctica, crearás la app de Wander
, que es un mapa de Google Maps con estilo. La app de Wander
te permite colocar marcadores en diferentes ubicaciones, ver tu ubicación en tiempo real y ver panorámicas de Street View.
3. Tarea 1: Configura el proyecto y obtén una clave de API
La API de Google Maps, al igual que la API de Places, requiere una clave de API. Para obtener la clave de API, registra tu proyecto en la Consola de APIs de Google. La clave de API está vinculada a un certificado digital que vincula la app con su autor. Para obtener más información acerca del uso de certificados digitales y la firma de tu app, consulta Firma tu app.
En esta práctica, usarás la clave de API para el certificado de depuración. El certificado de depuración tiene un diseño inseguro, como se describe en Cómo firmar tu compilación de depuración. Las aplicaciones para Android publicadas que usan la API de Google Maps requieren una segunda clave de API: la clave para el certificado de lanzamiento. Para conocer más detalles sobre cómo obtener un certificado de lanzamiento, consulta Cómo obtener una clave de API.
Android Studio incluye una plantilla de actividad de Google Maps, que genera un código de plantilla útil. El código de la plantilla incluye un archivo google_maps_api.xml
con un vínculo que simplifica la obtención de una clave de API.
1.1 Crea el proyecto Wander con la plantilla de Maps
- Crea un nuevo proyecto de Android Studio.
- Asigna el nombre "Wander" a la app nueva. Acepta los valores predeterminados hasta que llegues a la página Add an Activity.
- Selecciona la plantilla Google Maps Activity.
- Deja los valores predeterminados de Activity Name y Layout Name.
- Cambia el Título a "Wander". y haz clic en Finish.
Android Studio crea varios archivos adicionales relacionados con mapas:
google_maps_api**.xml**
Usa este archivo de configuración para conservar tu clave de API. La plantilla genera dos archivos google_maps_api.xml
: uno para la depuración y otro para el lanzamiento. El archivo de la clave de API para el certificado de depuración se encuentra en src/debug/res/values
. El archivo de la clave de API para el certificado de lanzamiento se encuentra en src/release/res/values
. En esta práctica, solo usamos el certificado de depuración.
activity_maps.xml
Este archivo de diseño contiene un solo fragmento que ocupa toda la pantalla. La clase SupportMapFragment
es una subclase de la clase Fragment
. Puedes incluir SupportMapFragment
en un archivo de diseño con una etiqueta <fragment>
en cualquier ViewGroup
, con un atributo adicional:
android:name="com.google.android.gms.maps.SupportMapFragment"
MapsActivity.java
El archivo MapsActivity.java
crea una instancia de la clase SupportMapFragment
y usa el método getMapAsync()
de la clase para preparar el mapa de Google Maps. La actividad que contiene el SupportMapFragment
debe implementar la interfaz de OnMapReadyCallback
y el método onMapReady()
de esa interfaz. El método getMapAsync()
muestra un objeto GoogleMap
, lo que indica que se cargó el mapa.
1.2 Cómo obtener la clave de API
- Abre la versión de depuración del archivo
google_maps_api.xml
.
El archivo incluye un comentario con una URL extensa. Los parámetros de la URL incluyen información específica sobre tu app.
- Copia y pega la URL en un navegador.
- Sigue las indicaciones para crear un proyecto en la Consola de APIs de Google. Debido a los parámetros de la URL proporcionada, la Consola de API sabe que debe habilitar automáticamente la API de Google Maps para Android.
- Crea una clave de API y haz clic en Restringir clave para restringir el uso de la clave a las apps para Android. La clave de API generada debe comenzar con
AIza
. - En el archivo
google_maps_api.xml
, pega la clave en la cadenagoogle_maps_key
, donde diceYOUR_KEY_HERE
. - Ejecuta tu app. Tienes un mapa incorporado en tu actividad con un marcador establecido en Sídney, Australia. (El marcador Sídney es parte de la plantilla y podrás cambiarlo más adelante).
4. Tarea 2: Agrega tipos de mapas y marcadores
Google Maps incluye varios tipos de mapas: normales, híbridos, satelitales, de terreno y "ninguno". En esta tarea, agregarás una barra de la app con un menú de opciones que le permite al usuario cambiar el tipo de mapa. Mueve la ubicación de partida del mapa a la de tu casa. A continuación, agregarás compatibilidad con marcadores, que indican ubicaciones únicas en un mapa y pueden incluir una etiqueta.
2.1 Agrega tipos de mapas
El tipo de mapa que desea el usuario depende del tipo de información que necesite. Cuando utilizas mapas para navegar en tu automóvil, resulta útil ver los nombres de las calles con claridad. Cuando haces senderismo, probablemente te preocupe más cuánto tienes que escalar para llegar a la cima de la montaña. En este paso, agregarás una barra de la app con un menú de opciones que le permite al usuario cambiar el tipo de mapa.
- Para crear un archivo XML de menú nuevo, haz clic con el botón derecho en el directorio
res
y selecciona New > Archivo de recursos de Android. - En el diálogo, asigna el nombre
map_options
al archivo. Elige Menú para el tipo de recurso. Haz clic en OK. - Reemplaza el código del archivo nuevo por el siguiente para crear las opciones del mapa. El argumento "ninguno" el tipo de mapa se omite porque "ninguno" resulta en la falta de ningún mapa.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/normal_map"
android:title="@string/normal_map"
app:showAsAction="never"/>
<item android:id="@+id/hybrid_map"
android:title="@string/hybrid_map"
app:showAsAction="never"/>
<item android:id="@+id/satellite_map"
android:title="@string/satellite_map"
app:showAsAction="never"/>
<item android:id="@+id/terrain_map"
android:title="@string/terrain_map"
app:showAsAction="never"/>
</menu>
- Crea recursos de cadenas para los atributos
title
. - En el archivo
MapsActivity
, cambia la clase para extender la claseAppCompatActivity
en lugar de extender la claseFragmentActivity
. Si usasAppCompatActivity
, se mostrará la barra de la app y, por lo tanto, el menú. - En
MapsActivity
, anula el métodoonCreateOptionsMenu()
y, luego, aumenta el archivomap_options
:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_options, menu);
return true;
}
- Para cambiar el tipo de mapa, utiliza el método
setMapType
() en el objetoGoogleMap
y pasa una de las constantes de tipo de mapa.
Anula el método onOptionsItemSelected()
. Pega el siguiente código para cambiar el tipo de mapa cuando el usuario selecciona una de las opciones del menú:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Change the map type based on the user's selection.
switch (item.getItemId()) {
case R.id.normal_map:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case R.id.hybrid_map:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
case R.id.satellite_map:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case R.id.terrain_map:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
- Ejecuta la app. Usa el menú de la barra de la aplicación para cambiar el tipo de mapa. Observa cómo cambia la apariencia del mapa.
2.2 Mueve la ubicación predeterminada del mapa
De forma predeterminada, la devolución de llamada onMapReady()
incluye el código que coloca un marcador en Sídney, Australia, donde se creó Google Maps. La devolución de llamada predeterminada también anima el mapa para que se desplaza lateralmente a Sídney. En este paso, harás que el mapa se desplace hasta la ubicación de tu casa sin colocar un marcador y, luego, aplicarás zoom al nivel que especifiques.
- En el método
onMapReady()
, quita el código que coloca el marcador en Sídney y mueve la cámara. - Ve a www.google.com/maps en tu navegador y encuentra tu dirección particular.
- Haz clic con el botón derecho en la ubicación y selecciona ¿Qué hay aquí?
Cerca de la parte inferior de la pantalla, aparece una ventana emergente con información sobre la ubicación, como la latitud y la longitud.
- Crea un objeto
LatLng
nuevo llamadohome
. En el objetoLatLng
, usa las coordenadas que encontraste de Google Maps en el navegador. - Crea una variable
float
llamadazoom
y configúrala en el nivel de zoom inicial que desees. La siguiente lista te brinda una idea del nivel de detalle que muestra cada nivel de zoom:
1
: Mundo5
: Tierra firme y continente10
: Ciudad15
: Calles20
: Edificios
- Crea un objeto
CameraUpdate
conCameraUpdateFactory.newLatLngZoom()
y pasa el objetoLatLng
y la variablezoom
. Para hacer zoom en la cámara y hacer zoom, llama amoveCamera()
en el objetoGoogleMap
y pasa el nuevo objetoCameraUpdate
:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
- Ejecuta la app. El mapa debería desplazarse lateralmente hasta tu casa y acercar el mapa al nivel que desees.
2.3 Cómo agregar marcadores de mapa
Google Maps puede seleccionar una ubicación mediante un marcador, que creas con la clase Marker
. El marcador predeterminado utiliza el ícono estándar de Google Maps: .
Puedes extender los marcadores para mostrar información contextual en ventanas de información.
En este paso, se agrega un marcador cuando el usuario toca y mantiene una ubicación en el mapa. Luego, agrega una InfoWindow
que muestre las coordenadas del marcador cuando se lo presiona.
- Crea un stub de método en
MapsActivity
llamadosetMapLongClick()
que tome unfinal
GoogleMap
como argumento y muestrevoid
:
private void setMapLongClick(final GoogleMap map) {}
- Usa el método
setOnMapLongClickListener()
del objetoGoogleMap
para colocar un marcador en el lugar donde el usuario lo toca y mantiene presionado. Pasa una instancia nueva deOnMapLongClickListener
que anule el métodoonMapLongClick()
. El argumento entrante es un objetoLatLng
que contiene las coordenadas de la ubicación que presionó el usuario:
private void setMapLongClick(final GoogleMap map) {
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
}
});
}
- Dentro de
onMapLongClick()
, llama al métodoaddMarker()
. Pasa un objetoMarkerOptions
nuevo con la posición establecida en elLatLng
pasado:
map.addMarker(new MarkerOptions().position(latLng));
- Llama a
setMapLongClick()
al final del métodoonMapReady()
. PasamMap
. - Ejecuta la app. Mantén presionado el mapa para colocar un marcador en una ubicación.
- Presiona el marcador, que lo centra en la pantalla.
Los botones de navegación aparecen en la parte inferior izquierda de la pantalla, lo que permite al usuario utilizar la app de Google Maps para navegar a la posición marcada.
Para agregar una ventana de información para el marcador, sigue estos pasos:
- En el objeto
MarkerOptions
, configura los campostitle
ysnippet
. - En
onMapLongClick()
, establece el campotitle
como "Pin colocado". Establece el camposnippet
en las coordenadas de la ubicación dentro del métodoaddMarker()
.
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng latLng) {
String snippet = String.format(Locale.getDefault(),
"Lat: %1$.5f, Long: %2$.5f",
latLng.latitude,
latLng.longitude);
map.addMarker(new MarkerOptions()
.position(latLng)
.title(getString(R.string.dropped_pin))
.snippet(snippet));
}
});
- Ejecuta la app. Para colocar un marcador de ubicación, mantenlo presionado en el mapa. Presiona el marcador para que aparezca la ventana de información.
2.4 Cómo agregar objetos de escucha de lugares de interés
De forma predeterminada, los lugares de interés aparecen en el mapa junto con sus íconos correspondientes. Los lugares de interés incluyen parques, escuelas, edificios gubernamentales y mucho más. Cuando el tipo de mapa se establece en normal
, también aparecen en el mapa los lugares de interés comerciales. Estos representan a empresas como tiendas, restaurantes y hoteles.
En este paso, agregarás un objeto GoogleMap.OnPoiClickListener
al mapa. Este objeto de escucha de clics coloca un marcador en el mapa de forma inmediata, en lugar de esperar que lo toquen. en espera. El objeto de escucha de clics también muestra la ventana de información que contiene el nombre del lugar de interés.
- Crea un stub de método en
MapsActivity
llamadosetPoiClick()
que tome unfinal
GoogleMap
como argumento y muestrevoid
:
private void setPoiClick(final GoogleMap map) {}
- En el método
setPoiClick()
, configura unOnPoiClickListener
en elGoogleMap
pasado:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
@Override
public void onPoiClick(PointOfInterest poi) {
}
});
- En el método
onPoiClick()
, coloca un marcador en la ubicación del lugar de interés. Establece el título con el nombre del lugar de interés. Guarda el resultado en una variable llamadapoiMarker
.
public void onPoiClick(PointOfInterest poi) {
Marker poiMarker = mMap.addMarker(new MarkerOptions()
.position(poi.latLng)
.title(poi.name);
}
- Llama a
showInfoWindow()
enpoiMarker
para que se muestre de inmediato la ventana de información.
poiMarker.showInfoWindow();
- Llama a
setPoiClick()
al final deonMapReady()
. PasamMap
. - Ejecuta tu app y busca un lugar de interés, como un parque. Presiona el lugar de interés para colocarle un marcador y mostrar su nombre en una ventana de información.
5. Tarea 3: Elige un estilo para tu mapa
Puedes personalizar Google Maps de muchas formas para darle a tu mapa un aspecto único.
Puedes personalizar un objeto MapFragment
con los atributos XML disponibles, como lo harías con cualquier otro fragmento. Sin embargo, en este paso, personalizarás la apariencia del contenido de MapFragment
mediante métodos en el objeto GoogleMap
. Puedes utilizar el Asistente de diseño en línea para agregar un diseño a tu mapa y personalizar tus marcadores. También agregarás un objeto GroundOverlay
a la ubicación de tu casa que se ajuste y rote con el mapa.
3.1 Cómo agregar un diseño al mapa
Para crear un diseño personalizado para tu mapa, debes generar un archivo JSON que especifique cómo se muestran los componentes del mapa.No es necesario que crees este archivo manualmente, ya que Google proporciona el Asistente de diseño, que genera el archivo JSON después de que aplicas diseño visual en el mapa. En esta práctica, diseñarás el mapa para el "modo nocturno", lo que significa que el mapa usa colores tenues y un contraste bajo para su uso por la noche.
- Navega a https://mapstyle.withgoogle.com/ en tu navegador.
- Selecciona Crear un diseño.
- Selecciona el tema Noche.
- Haz clic en Más opciones en la parte inferior del menú.
- En la parte inferior de la lista Tipo de componente, selecciona Agua > Relleno. Cambia el color del agua a azul oscuro (por ejemplo, #160064).
- Haz clic en Finalizar. Copia el código JSON de la ventana emergente que aparecerá.
- En Android Studio, crea un directorio de recursos llamado
raw
en el directoriores
. Crea un archivo enres/raw
llamadomap_style.json
. - Pega el código JSON en el archivo de recursos nuevo.
- Para establecer el diseño JSON en el mapa, llama a
setMapStyle()
en el objetoGoogleMap
. Pasa un objetoMapStyleOptions
, que carga el archivo JSON. El métodosetMapStyle()
muestra un valor booleano que indica el éxito del diseño. Si no se puede cargar, el método arroja unaResources.NotFoundException
.
Copia el siguiente código en el método onMapReady()
para definir el diseño del mapa. Es posible que debas crear una cadena TAG
para tus instrucciones de registro:
try {
// Customize the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.map_style));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
- Ejecuta tu app. El nuevo diseño debería mostrarse cuando el mapa esté en el modo
normal
.
3.2 Cómo cambiar el estilo del marcador
Puedes aplicar diseño a los marcadores del mapa para personalizar aún más tu mapa. En este paso, cambiarás los marcadores rojos predeterminados para que coincidan con el esquema de colores del modo nocturno.
- En el método
onMapLongClick()
, agrega la siguiente línea de código al constructorMarkerOptions()
para usar el marcador predeterminado, pero cambiar el color a azul:
.icon(BitmapDescriptorFactory.defaultMarker
(BitmapDescriptorFactory.HUE_BLUE))
- Ejecuta la app. Los marcadores que coloques ahora tendrán una sombra de color azul, lo que es más coherente con el tema del modo nocturno de la app.
Ten en cuenta que los marcadores de lugares de interés siguen siendo rojos porque no agregaste un diseño al método onPoiClick()
.
3.3 Cómo agregar una superposición
Una forma de personalizar el mapa de Google Maps es dibujar sobre él. Esta técnica es útil si quieres destacar un tipo de ubicación en particular, como puntos de pesca populares. Se admiten tres tipos de superposiciones:
- Formas: Puedes agregar polilíneas, polígonos y círculos al mapa.
- Objetos
TileOverlay
: Una superposición de mosaicos define un conjunto de imágenes que se agregan sobre los mosaicos del mapa base. Las superposiciones de mosaicos son útiles cuando deseas agregar muchas imágenes al mapa. Una superposición de mosaicos típica abarca un área geográfica extensa. - Objetos
GroundOverlay
: Una superposición de suelo es una imagen que se fija a un mapa. A diferencia de los marcadores, las superposiciones de suelo se orientan a la superficie de la Tierra y no a la pantalla. La rotación, la inclinación o el zoom del mapa cambian la orientación de la imagen. Las superposiciones de suelo resultan útiles cuando deseas fijar una sola imagen en un área del mapa.
En este paso, agregarás una superposición de suelo con forma de Android a la ubicación de tu casa.
- Descarga esta imagen de Android y guárdala en la carpeta
res/drawable
. - En
onMapReady()
, después de la llamada para mover la cámara a la posición inicial, crea un objetoGroundOverlayOptions
. Asigna el objeto a una variable llamadahomeOverlay
:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
- Usa el método
BitmapDescriptorFactory.fromResource()
para crear un objetoBitmapDescriptor
a partir de la imagen anterior. Pasa el objeto al métodoimage()
del objetoGroundOverlayOptions
:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android));
- Configura la propiedad
position
para el objetoGroundOverlayOptions
llamando al métodoposition()
. Pasa el objetoLatLng
dehome
y unafloat
para el ancho en metros de la superposición deseada. Para este ejemplo, un ancho de 100 m funciona bien:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromResource(R.drawable.android))
.position(home, 100);
- Llama a
addGroundOverlay()
en el objetoGoogleMap
. Pasa tu objetoGroundOverlayOptions
:
mMap.addGroundOverlay(homeOverlay);
- Ejecuta la app. Acerca la ubicación de tu casa y verás la imagen de Android como una superposición.
6. Tarea 4: Habilitar el seguimiento de la ubicación y Street View
A menudo, los usuarios utilizan Google Maps para ver su ubicación actual. Puedes obtener la ubicación del dispositivo con la API de Location Services. Para mostrar la ubicación del dispositivo en el mapa sin usar más datos de Location
, puedes usar la capa de datos de ubicación.
La capa de datos de ubicación agrega el botón Mi ubicación en la parte superior derecha del mapa. Cuando el usuario presiona el botón, el mapa se centra en la ubicación del dispositivo. La ubicación se muestra como un punto azul si el dispositivo está quieto y como un corchete angular azul si el dispositivo está en movimiento.
Puedes proporcionar información adicional sobre una ubicación usando Google Street View, que es una foto panorámica navegable de una ubicación determinada.
En esta tarea, habilitarás la capa de datos de ubicación y Street View para que, cuando el usuario presione la ventana de información del marcador de lugares de interés, el mapa entre en el modo Street View.
4.1 Habilita el seguimiento de la ubicación
Para habilitar el seguimiento de ubicación en Google Maps, se necesita una sola línea de código. Sin embargo, debes asegurarte de que el usuario haya otorgado permisos de ubicación (con el modelo de permisos de tiempo de ejecución).
En este paso, debes solicitar permisos de ubicación y habilitar el seguimiento de ubicación.
- En el archivo
AndroidManifest.xml
, verifica que el permisoFINE_LOCATION
ya esté presente. Android Studio insertó este permiso cuando seleccionaste la plantilla de Google Maps. - Para habilitar el seguimiento de ubicación en tu app, crea un método en
MapsActivity
llamadoenableMyLocation()
que no tome argumentos ni devuelva nada. - Define el método
enableMyLocation()
. Verifica el permisoACCESS_FINE_LOCATION
. Si se otorga el permiso, habilita la capa de ubicación. De lo contrario, solicita el permiso:
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION_PERMISSION);
}
}
- Llama a
enableMyLocation()
desde la devolución de llamadaonMapReady()
para habilitar la capa de ubicación. - Anula el método
onRequestPermissionsResult()
. Si se otorga el permiso, llama aenableMyLocation()
:
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
// Check if location permissions are granted and if so enable the
// location data layer.
switch (requestCode) {
case REQUEST_LOCATION_PERMISSION:
if (grantResults.length > 0
&& grantResults[0]
== PackageManager.PERMISSION_GRANTED) {
enableMyLocation();
break;
}
}
}
- Ejecuta la app. La esquina superior derecha ahora contiene el botón My Location, que muestra la ubicación actual del dispositivo.
4.2 Habilitar Street View
Google Maps ofrece Street View, que es una vista panorámica de una ubicación con controles para navegar por una ruta designada. Street View no tiene cobertura global.
En este paso, habilitas una panorámica de Street View que se activa cuando el usuario presiona la ventana de información de un lugar de interés. Debes seguir dos pasos:
- Distingue los marcadores de lugares de interés de otros marcadores, ya que quieres que la funcionalidad de tu app funcione solo en los marcadores de lugares de interés. De esta manera, puedes iniciar Street View cuando el usuario presiona una ventana de información de lugares de interés, pero no cuando presiona cualquier otro tipo de marcador.
La clase Marker
incluye un método setTag()
que te permite adjuntar datos. (los datos pueden ser cualquier cosa que se extienda desde Object
). Establecerás una etiqueta en los marcadores que se crean cuando los usuarios hacen clic en un lugar de interés.
- Cuando el usuario presione una ventana de información etiquetada en una
OnInfoWindowClickListener
, reemplazaMapFragment
porStreetViewPanoramaFragment
. (El siguiente código usaSupportMapFragment
ySupportStreetViewPanoramaFragment
para admitir versiones de Android anteriores a la API 12).
Si alguno de los fragmentos cambia durante el tiempo de ejecución, debes agregarlos en la clase Activity
que los contiene y no de forma estática en XML.
Cómo etiquetar el marcador de lugares de interés
- En la devolución de llamada
onPoiClick()
, llama asetTag()
enpoiMarker
. Pasa cualquier cadena arbitraria:
poiMarker.setTag("poi");
Reemplaza el SupportMapFragment estático con una instancia de tiempo de ejecución
- Abre
activity_maps.xml
y cambia el elemento a un diseño de marco que sirva como contenedor para tus fragmentos:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- En
onCreate()
, enMapsActivity
, quita el código que encuentra elSupportMapFragment
por ID, porque ya no hay unSupportMapFragment
estático en el XML. En su lugar, crea una nueva instancia de entorno de ejecución deSupportMapFragment
llamando aSupportMapFragment.newInstance()
:
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
- Agrega el fragmento a
FrameLayout
usando una transacción de fragmento con elFragmentManager
:
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, mapFragment).commit();
- Mantén la línea de código que activa la carga asíncrona del mapa:
mapFragment.getMapAsync(this);
Configura un OnInfoWindowClickListener y verifica la etiqueta del marcador
- Crea un stub de método en
MapsActivity
llamadosetInfoWindowClickToPanorama()
que tome unGoogleMap
como argumento y muestrevoid
:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
- Establece un
OnInfoWindowClickListener
enGoogleMap
:
map.setOnInfoWindowClickListener(
new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
}
});
- En el método
onInfoWindowClick()
, verifica si el marcador contiene la etiqueta de cadena que estableciste en el métodoonPoiClick()
:
if (marker.getTag() == "poi") {}
Cómo reemplazar SupportMapFragment con SupportStreetViewPanoramaFragment
- Cuando el marcador contenga la etiqueta, especifica la ubicación de la panorámica de Street View con un objeto
StreetViewPanoramaOptions
. Establece la propiedadposition
del objeto en la posición del marcador que se pasó:
StreetViewPanoramaOptions options =
new StreetViewPanoramaOptions().position(
marker.getPosition());
- Crea una instancia nueva de
SupportStreetViewPanoramaFragment
y pasa el objetooptions
que creaste:
SupportStreetViewPanoramaFragment streetViewFragment
= SupportStreetViewPanoramaFragment
.newInstance(options);
- Inicia una transacción de fragmento. Reemplaza el contenido del contenedor del fragmento con el fragmento nuevo,
streetViewFragment
. Agrega la transacción a la pila de actividades, de modo que cuando presiones Atrás, regreses aSupportMapFragment
y no salgas de la app:
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,
streetViewFragment)
.addToBackStack(null).commit();
- Llama a
setInfoWindowClickToPanorama(mMap)
enonMapReady()
después de la llamada asetPoiClick().
. - Ejecuta la app. Acerca la imagen a una ciudad que tenga cobertura de Street View, como Mountain View (sede de la sede central de Google), y busca un lugar de interés, como un parque. Presiona el lugar de interés para colocar un marcador y ver la ventana de información. Presiona la ventana de información para ingresar al modo Street View correspondiente a la ubicación del marcador. Presiona el botón Atrás para volver al fragmento de mapa.
7. Código de solución
Código de solución de Wander
.
8. Desafío de programación
Desafío: Si presionas la ventana de información de un lugar de interés en una ubicación sin cobertura de Street View, verás una pantalla negra.
- Para verificar si Street View está disponible en un área, implementa la devolución de llamada
OnStreetViewPanomaraReady
en combinación conStreetViewPanorama.OnStreetViewPanoramaChangeListener
. - Si Street View no está disponible en un área seleccionada, vuelve al fragmento del mapa y muestra un error.
9. Resumen
- Para usar la API de Google Maps, necesitas una clave de API de la Consola de APIs de Google.
- En Android Studio, el uso de la plantilla de actividad de Google Maps genera un
Activity
con un soloSupportMapFragment
en el diseño de la app. La plantilla también agrega elACCESS_FINE_PERMISSION
al manifiesto de la app, implementa elOnMapReadyCallback
en tu actividad y anula el métodoonMapReady()
requerido.
Para cambiar el tipo de mapa de una GoogleMap
durante el tiempo de ejecución, usa el método GoogleMap.setMapType()
. Un mapa de Google Maps puede ser uno de los siguientes tipos de mapas:
- Normal: Mapa de ruta típico Muestra rutas, algunas características creadas por el hombre y características naturales importantes, como ríos. También muestra etiquetas de rutas y características.
- Híbrido: Muestra datos de fotos satelitales con mapas de rutas agregados. También muestra etiquetas de rutas y características.
- Satélite: Muestra los datos de las fotografías. No se ven etiquetas de carreteras y elementos.
- Terreno: Datos topográficos. El mapa incluye colores, líneas de contorno y etiquetas, y sombras de perspectiva. También muestra algunas rutas y etiquetas.
- Ninguna**:** No hay un mapa.
Acerca de Google Maps:
- Un marcador es un indicador de una ubicación geográfica específica.
- Cuando el marcador se presiona, el comportamiento predeterminado consiste en mostrar una ventana de información con datos sobre la ubicación.
- De forma predeterminada, los puntos de interés (POI) aparecen en el mapa básico con sus íconos correspondientes. Los lugares de interés incluyen parques, escuelas, edificios gubernamentales y mucho más.
- Además, los lugares de interés comerciales (tiendas, restaurantes, hoteles, etc.) aparecen de forma predeterminada en el mapa cuando el tipo de mapa es
normal
. - Puedes capturar clics en los lugares de interés con el ícono
OnPoiClickListener
. - Puedes cambiar la apariencia visual de casi todos los elementos de un mapa de Google Maps con el Asistente de diseño. El asistente de diseño genera un archivo JSON que se pasa al mapa de Google Maps con el método
setMapStyle()
. - Si deseas personalizar los marcadores, puedes cambiar el color predeterminado o reemplazar el ícono predeterminado por una imagen personalizada.
Otra información importante:
- Usa una superposición de suelo para fijar una imagen a una ubicación geográfica.
- Usa un objeto
GroundOverlayOptions
para especificar la imagen, su tamaño en metros y su posición. Pasa este objeto al métodoGoogleMap.addGroundOverlay()
para establecer la superposición en el mapa. - Siempre que la app tenga el permiso
ACCESS_FINE_LOCATION
, puedes habilitar el seguimiento de la ubicación con el métodomMap.setMyLocationEnabled(true)
. - Google Street View proporciona vistas panorámicas de 360 grados de rutas designadas en su área de cobertura.
- Utiliza el método
StreetViewPanoramaFragment.newInstance()
para crear un nuevo fragmento de Street View. - Para especificar las opciones de la vista, usa un objeto
StreetViewPanoramaOptions
. Pasa el objeto al métodonewInstance()
.
10. Más información
La documentación de conceptos relacionados se encuentra en 9.1: API de Google Maps.
Documentación para desarrolladores de Android:
- Cómo comenzar a utilizar la API de Google Maps para Android
- Cómo agregar un mapa con un marcador
- Objetos de mapa
- Cómo agregar un mapa con diseños
- Street View
- Superposiciones de suelo
Documentación de referencia:
11. Tarea
En esta sección, se enumeran las posibles actividades para el hogar para los alumnos que trabajan en este codelab como parte de un curso dirigido por un instructor. Depende del instructor hacer lo siguiente:
- Si es necesario, asigna una tarea.
- Comunicarles a los alumnos cómo enviar las actividades para el hogar.
- Califica las actividades para el hogar.
Los instructores pueden usar estas sugerencias en la medida que quieran y deben asignar cualquier otra actividad para el hogar que consideren apropiada.
Si estás trabajando en este codelab por tu cuenta, usa estas actividades para el hogar para probar tus conocimientos.
Compila y ejecuta una app
- Crea una app nueva que use la plantilla de actividad de Google Maps, que carga Google Maps cuando se inicia la app.
- Una vez cargado el mapa de Google Maps, mueve la cámara a la ubicación de tu escuela, de tu casa o de alguna otra ubicación que tenga un significado para ti.
- Agrega dos marcadores al mapa: uno en la ubicación de tu escuela y otro en tu casa u otra ubicación significativa.
- Para personalizar los íconos de los marcadores, cambia el color predeterminado o reemplaza el ícono predeterminado por una imagen personalizada.
Pista: Consulta la documentación de onMapReady (GoogleMap googleMap)
.
Responde estas preguntas:
Pregunta 1
¿A qué método se llama cuando el mapa se carga y está listo para usarse en la app?
onMapReady (
GoogleMap
googleMap)
onMapLoaded (
GoogleMap
googleMap)
onMapCreate (
GoogleMap
googleMap)
onMapInitialize (
GoogleMap
googleMap)
Pregunta 2
¿Qué componentes de Android puedes usar para incluir Google Maps en tu app?
MapView
yMapFragment
MapFragment
yMapActivity
MapView
yMapActivity
- Solo
MapFragment
Pregunta 3
¿Qué tipos de mapas ofrece la Google Maps Android API?
- Normal, híbrido, terreno, satélite y hoja de ruta
- Normal, híbrido, terreno, satélite y "ninguno"
- Híbrido, terreno, satélite, hoja de ruta y “ninguno”
- Normal, terreno, satélite, mapa de imagen y "ninguno"
Pregunta 4
¿Qué interfaz implementas para agregar la funcionalidad de clic en un lugar de interés?
GoogleMap.OnPoiListener
GoogleMap.OnPoiClickListener
GoogleMap.OnPoiClick
GoogleMap.OnPoiClicked
Envía tu app para que se la califique
Orientación para calificadores
Verifica que la app tenga las siguientes funciones:
- Cuando se inicia la app, se muestra correctamente el mapa de Google Maps, lo que indica que se generó correctamente una clave de API.
- Una vez cargado el mapa de Google Maps, la cámara se mueve a la ubicación de la casa o de la escuela del estudiante. En el código, este paso debe ocurrir en el método de devolución de llamada
onMapReady (GoogleMap googleMap)
. - Los marcadores se muestran en la ubicación de la escuela del estudiante y en otra ubicación, como la casa del estudiante.
- Los dos marcadores están personalizados. Por ejemplo, los marcadores usan un color distinto del rojo predeterminado o usan un ícono personalizado.
12. Próximo codelab
Para ver todos los codelabs del curso de capacitación Desarrollo avanzado de Android, visita la página de destino de Codelabs de Desarrollo avanzado de Android.