Android avanzado en Kotlin 04.1: Android Google Maps

Este codelab es parte del curso avanzado de Android en Kotlin. Obtendrá el mayor valor de este curso si trabaja con los laboratorios de código en secuencia, pero no es obligatorio. Todos los codelabs del curso se enumeran en la página de inicio de Advanced Android in Kotlin codelabs .

La creación de aplicaciones con Google Maps le permite agregar funciones a su aplicación, como imágenes satelitales, controles de interfaz de usuario sólidos para mapas, seguimiento de ubicación y marcadores de ubicación. Puede agregar valor a Google Maps estándar mostrando información de su propio conjunto de datos, como la ubicación de áreas de pesca o escalada conocidas. También puede crear juegos en los que el jugador explora el mundo físico, como en una búsqueda del tesoro o incluso juegos de realidad aumentada.

En esta lección, creará una aplicación de Google Maps llamada Wander que muestra mapas personalizados y muestra la ubicación del usuario.

Prerrequisitos

Conocimiento de lo siguiente:

  • Cómo crear una aplicación básica de Android y ejecutarla con Android Studio.
  • Cómo crear y administrar recursos, como cadenas.
  • Cómo refactorizar el código y cambiar el nombre de las variables con Android Studio.
  • Cómo utilizar un mapa de Google como usuario.
  • Cómo configurar los permisos de tiempo de ejecución.

Lo que aprenderás

  • Cómo obtener una clave API de la Consola API de Google y registrar la clave en su aplicación
  • Cómo integrar un mapa de Google en su aplicación
  • Cómo mostrar diferentes tipos de mapas
  • Cómo diseñar el mapa de Google
  • Cómo agregar marcadores a su mapa
  • Cómo permitir que el usuario coloque un marcador en un punto de interés (PDI)
  • Cómo habilitar el seguimiento de ubicación
  • Cómo crear la aplicación The Wander , que tiene un mapa de Google incrustado
  • Cómo crear funciones personalizadas para su aplicación, como marcadores y estilos
  • Cómo habilitar el seguimiento de la ubicación en su aplicación

En este laboratorio de código, crea la aplicación Wander , que muestra un mapa de Google con un estilo personalizado. La aplicación Wander le permite colocar marcadores en ubicaciones, agregar superposiciones y ver su ubicación en tiempo real.

5b12eda7f467bc2f.png

El SDK de Maps para Android requiere una clave API. Para obtener la clave API, registre su proyecto en la página API y servicios . La clave de API está vinculada a un certificado digital que vincula la aplicación a su autor. Para obtener más información sobre el uso de certificados digitales y la firma de su aplicación, consulte Firmar su aplicación .

En este laboratorio de código, usa la clave API para el certificado de depuración. El certificado de depuración no es seguro por diseño, como se describe en Firma tu compilación de depuración . Las aplicaciones de Android publicadas que utilizan el SDK de Maps para Android requieren una segunda clave de API: la clave para el certificado de versión. Para obtener más información sobre cómo obtener un certificado de versión, consulte 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 que contiene un vínculo que simplifica la obtención de una clave API.

Paso 1: crea el proyecto Wander con la plantilla de mapas

  1. Crea un nuevo proyecto de Android Studio.
  2. Seleccione la plantilla Actividad de Google Maps .

d6b874bb19ea68cd.png

  1. Nombra el proyecto Wander .
  2. Establezca el nivel mínimo de API en API 19 . Asegúrese de que el idioma sea Kotlin .
  3. Haga clic en Finalizar .
  4. Una vez que la aplicación haya terminado de compilarse, eche un vistazo a su proyecto y a los siguientes archivos relacionados con mapas que Android Studio crea para usted:

google_maps_api.xml: utiliza este archivo de configuración para almacenar su clave de API. La plantilla genera dos archivos google_maps_api.xml : uno para depuración y otro para publicación. 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 versión se encuentra en src / release / res / values . En este codelab, solo usa 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 . Un SupportMapFragment es la forma más sencilla de colocar un mapa en una aplicación. Es un envoltorio alrededor de una vista de un mapa para manejar automáticamente las necesidades necesarias del ciclo de vida.

Puede incluir SupportMapFragment en un archivo de diseño utilizando una etiqueta <fragment> en cualquier ViewGroup , con un atributo de name adicional.

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.java : el archivo MapsActivity.kt crea una instancia de SupportMapFragment en el método onCreate() y utiliza la clase ' getMapAsync () para inicializar automáticamente el sistema de mapas y la vista. La actividad que contiene SupportMapFragment debe implementar la interfaz OnMapReadyCallback y el método onMapReady() esa interfaz. El método onMapReady() se llama cuando se carga el mapa.

Paso 2: Obtén la clave de API

  1. Abra la versión de depuración del archivo google_maps_api.xml .
  2. En el archivo, busque un comentario con una URL larga. Los parámetros de la URL incluyen información específica sobre su aplicación.
  3. Copie y pegue la URL en un navegador.
  4. Siga las instrucciones para crear un proyecto en la página API y servicios . Debido a los parámetros en la URL proporcionada, la página sabe que habilita automáticamente el SDK de Maps para Android.
  5. Haga clic en Crear una clave de API .
  6. En la página siguiente, vaya a la sección Claves API y haga clic en la clave que acaba de crear.
  7. Haga clic en Restringir clave y seleccione Maps SDK para Android para restringir el uso de la clave a las aplicaciones de Android.
  8. Copie la clave API generada. Comienza con " AIza" .
  9. En el archivo google_maps_api.xml , pegue la clave en la cadena google_maps_key donde dice YOUR_KEY_HERE .
  10. Ejecute su aplicación. Debería ver un mapa incrustado en su actividad con un marcador establecido en Sydney, Australia. (El marcador de Sydney es parte de la plantilla y lo cambia más tarde).

34dc9dd877c90996.png

Paso 3: cambiar el nombre de mMap

MapsActivity tiene una privada lateinit var llamada mMap , que es de tipo GoogleMap . Para seguir las convenciones de nomenclatura de Kotlin, cambie el nombre de mMap a map .

  1. En MapsActivity , haga clic con el botón derecho en mMap y haga clic en Refactorizar > Cambiar nombre ...

e713ccb3384450c6.png

  1. Cambie el nombre de la variable a map .

Observe cómo todas las referencias a mMap en la función onMapReady() también cambian a map .

Google Maps incluye varios tipos de mapas: normal, híbrido, satelital, terreno y "ninguno" (para ningún mapa).

Mapa normal

Mapa satelital

Mapa híbrido

Mapa del terreno

Cada tipo de mapa proporciona diferentes tipos de información. Por ejemplo, al usar mapas para navegar en un automóvil, es útil ver los nombres de las calles, por lo que podría usar la opción normal. Cuando esté de excursión, el mapa del terreno podría ser útil para decidir cuánto más tiene que escalar para llegar a la cima.

En esta tarea usted:

  1. Agregue una barra de aplicaciones con un menú de opciones que le permita al usuario cambiar el tipo de mapa.
  2. Mueva la ubicación inicial del mapa a su propia ubicación de inicio.
  3. Agregue soporte para marcadores, que indican ubicaciones individuales en un mapa y pueden incluir una etiqueta.

Agregar menú para tipos de mapas

En este paso, agrega una barra de aplicaciones con un menú de opciones que permite al usuario cambiar el tipo de mapa.

  1. Para crear un nuevo archivo XML de menú, haga clic con el botón derecho en su directorio res y seleccione Nuevo > Archivo de recursos de Android .
  2. En el cuadro de diálogo, map_options nombre al archivo map_options .
  3. Elija Menú para el tipo de recurso.
  4. Haga clic en Aceptar .
  5. En la pestaña Código , reemplace el código en el nuevo archivo con el siguiente código para crear las opciones del menú del mapa. El tipo de mapa "ninguno" se omite porque "ninguno" da como resultado la falta de ningún mapa. Este paso genera un error, pero lo resuelve en el siguiente paso.
<?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>
  1. En strings.xml , agregue recursos para los atributos del title con el fin de resolver los errores.
<resources>
   ...
   <string name="normal_map">Normal Map</string>
   <string name="hybrid_map">Hybrid Map</string>
   <string name="satellite_map">Satellite Map</string>
   <string name="terrain_map">Terrain Map</string>
   <string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
   <string name="dropped_pin">Dropped Pin</string>
   <string name="poi">poi</string>
</resources>
  1. En MapsActivity , anule el método onCreateOptionsMenu() e infle el menú del archivo de recursos map_options .
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. En MapsActivity.kt , anule el método onOptionsItemSelected() . Cambie el tipo de mapa utilizando constantes de tipo mapa para reflejar la selección del usuario.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
   // Change the map type based on the user's selection.
   R.id.normal_map -> {
       map.mapType = GoogleMap.MAP_TYPE_NORMAL
       true
   }
   R.id.hybrid_map -> {
       map.mapType = GoogleMap.MAP_TYPE_HYBRID
       true
   }
   R.id.satellite_map -> {
       map.mapType = GoogleMap.MAP_TYPE_SATELLITE
       true
   }
   R.id.terrain_map -> {
       map.mapType = GoogleMap.MAP_TYPE_TERRAIN
       true
   }
   else -> super.onOptionsItemSelected(item)
}
  1. Ejecute la aplicación.
  2. Hacer clic 428da163b831115b.png para cambiar el tipo de mapa. Observe cómo cambia la apariencia del mapa entre los diferentes modos.

6fa42970d87f5dc7.png

De forma predeterminada, la devolución de llamada onMapReady() incluye código que coloca un marcador en Sydney, Australia, donde se creó Google Maps. La devolución de llamada predeterminada también anima el mapa para desplazarse a Sydney.

En esta tarea, hace que la cámara del mapa se mueva a su casa, haga zoom a un nivel que especifique y coloque un marcador allí.

Paso 1: acércate a tu casa y agrega un marcador

  1. En el archivo MapsActivity.kt , busque el método onMapReady() . Elimina el código que coloca el marcador en Sydney y mueve la cámara. Así es como debería verse su método ahora.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Encuentre la latitud y longitud de su hogar siguiendo estas instrucciones .
  2. Cree un valor para la latitud y un valor para la longitud, e ingrese sus valores flotantes.
val latitude = 37.422160
val longitude = -122.084270
  1. Crear un nuevo LatLng objeto llamado homeLatLng . En el objeto homeLatLng , pase los valores que acaba de crear.
val homeLatLng = LatLng(latitude, longitude)
  1. Cree un val de qué tan ampliado desea estar en el mapa. Utilice el nivel de zoom 15f.
val zoomLevel = 15f

El nivel de zoom controla qué tan ampliado está usted en el mapa. La siguiente lista le da una idea del nivel de detalle que muestra cada nivel de zoom:

  • 1 : Mundo
  • 5 : Masa terrestre / continente
  • 10 : Ciudad
  • 15 : Calles
  • 20 : Edificios
  1. Mover la cámara a homeLatLng llamando al moveCamera() función en el map objeto y pasar en un CameraUpdate objeto utilizando CameraUpdateFactory.newLatLngZoom() . Pase el objeto homeLatLng y el zoomLevel .
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Agrega un marcador al mapa en homeLatLng .
map.addMarker(MarkerOptions().position(homeLatLng))

Su método final debería verse así:

override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

   //These coordinates represent the latitude and longitude of the Googleplex.
   val latitude = 37.422160
   val longitude = -122.084270
   val zoomLevel = 15f

   val homeLatLng = LatLng(latitude, longitude)
   map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
   map.addMarker(MarkerOptions().position(homeLatLng))
}
  1. Ejecute su aplicación. El mapa debe desplazarse hasta su casa, hacer zoom al nivel deseado y colocar un marcador en su casa.

fc939024778ee76.png

Paso 2: Permita que los usuarios agreguen un marcador con un clic largo

En este paso, agrega un marcador cuando el usuario toca y mantiene una ubicación en el mapa.

  1. Cree un código auxiliar de método en MapsActivity llamado setMapLongClick() que toma un GoogleMap como argumento.
  2. Adjunte un detector setOnMapLongClickListener al objeto de mapa.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. En setOnMapLongClickListener() , llame al método addMarker() . Pase un nuevo objeto MarkerOptions con la posición establecida en LatLng .
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. Al final del método onMapReady() , llame a setMapLongClick() con map .
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Ejecute su aplicación.
  2. Mantén presionado el mapa para colocar un marcador en una ubicación.
  3. Toque el marcador, que lo centra en la pantalla.

4ff8d1c1db3bca9e.png

Paso 3: agrega una ventana de información para el marcador

En este paso, agrega una InfoWindow que muestra las coordenadas del marcador cuando se InfoWindow el marcador.

  1. En setMapLongClick()setOnMapLongClickListener() , cree un val para el snippet . Un fragmento es texto adicional que se muestra después del título. Su fragmento muestra la latitud y la longitud de un marcador.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A snippet is additional text that's displayed after the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. En addMarker() , establezca el title del marcador en Dropped Pin usando una R.string. dropped_pin cadena dropped_pin .
  2. Establezca el snippet del marcador en snippet .

La función completa se ve así:

private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A Snippet is Additional text that's displayed below the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet)
              
       )
   }
}
  1. Ejecute su aplicación.
  2. Toque y mantenga presionado el mapa para colocar un marcador de ubicación.
  3. Toque el marcador para mostrar la ventana de información.

63f210e6e47dfa29.png

Paso 4: Agregar oyente de puntos de interés

De forma predeterminada, los puntos de interés (PDI) aparecen en el mapa junto con sus iconos correspondientes. Los PDI incluyen parques, escuelas, edificios gubernamentales y más. Cuando el tipo de mapa se establece en normal , los puntos de interés comerciales también aparecen en el mapa. Los puntos de interés comerciales representan empresas, como tiendas, restaurantes y hoteles.

En este paso, agrega un GoogleMap.OnPoiClickListener al mapa. Este oyente de clics coloca un marcador en el mapa inmediatamente cuando el usuario hace clic en un PDI. El oyente de clics también muestra una ventana de información que contiene el nombre del PDI.

  1. Cree un código auxiliar de método en MapsActivity llamado setPoiClick() que toma un GoogleMap como argumento.
  2. En el método setPoiClick() , configure un OnPoiClickListener en el GoogleMap pasado.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. En setOnPoiClickListener() , cree un val poiMarker para el marcador.
  2. map.addMarker() un marcador usando map.addMarker() con MarkerOptions configurando el title con el nombre del PDI.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. En la función setOnPoiClickListener() , llame a showInfoWindow() en poiMarker para mostrar inmediatamente la ventana de información.
poiMarker.showInfoWindow()

Su código final para la función setPoiClick() debería verse así.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. Al final de onMapReady() , llame a setPoiClick() y pase el map .
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Ejecute su aplicación y busque un PDI, como un parque o una cafetería.
  2. Toque el PDI para colocar un marcador en él y mostrar el nombre del PDI en una ventana de información.

f4b0972c75d5fa5f.png

Puede personalizar Google Maps de muchas formas, dando a su mapa un aspecto y una sensación únicos.

Puede personalizar un objeto MapFragment utilizando los atributos XML disponibles, como personalizaría cualquier otro fragmento. Sin embargo, en este paso, personaliza la apariencia del contenido del MapFragment , utilizando métodos en el objeto GoogleMap .

Para crear un estilo personalizado para su mapa, genera un archivo JSON que especifica cómo se muestran las características en el mapa. No es necesario que cree este archivo JSON manualmente. Google proporciona el asistente de estilo de la plataforma de Maps , que genera el JSON después de diseñar visualmente el mapa. En esta tarea, diseña el mapa con un tema retro, lo que significa que el mapa usa colores antiguos y agrega carreteras de colores.

Paso 1: crea un estilo para tu mapa

  1. Vaya a https://mapstyle.withgoogle.com/ en su navegador.
  2. Seleccione Crear un estilo .
  3. Seleccione Retro .

208b3d3aeab0d9b6.png

  1. Haga clic en Más opciones .

4a35faaf9535ee82.png

  1. Seleccione Carretera > Relleno .
  2. Cambie el color de las carreteras a cualquier color que elija (como rosa).

92c3293749293a4c.png

  1. Haga clic en Finalizar .

f1bfe8585eb69480.png

  1. Copie el código JSON del cuadro de diálogo resultante y, si lo desea, guárdelo en una nota de texto sin formato para usar en el siguiente paso.

3c32168b299d6420.png

Paso 2: agrega el estilo a tu mapa

  1. En Android Studio, en el directorio res , cree un directorio de recursos y asígnele el nombre sin raw . Utiliza los recursos del directorio sin raw como el código JSON.
  2. Cree un archivo en res/raw llamado map_style.json .
  3. Pegue su código JSON escondido en el nuevo archivo de recursos.
  4. En MapsActivity , cree una variable de clase TAG sobre el método onCreate() . Esto se utiliza para fines de registro.
private val TAG = MapsActivity::class.java.simpleName
  1. También en MapsActivity , cree una función setMapStyle() que setMapStyle() un GoogleMap .
  2. En setMapStyle() , agregue un bloque try{} .
  3. En el bloque try{} , cree un val success para el éxito del estilo. (Agrega el siguiente bloque de captura).
  4. En el bloque try{} , establezca el estilo JSON en el mapa, llame a setMapStyle() en el objeto GoogleMap . Pase un objeto MapStyleOptions , que carga el archivo JSON.
  5. Asigne el resultado al success . El método setMapStyle() devuelve un valor booleano que indica el estado setMapStyle() de analizar el archivo de estilo y establecer el estilo.
private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )
   }
}
  1. Agregue una declaración if para que el success sea ​​falso. Si el estilo no tiene éxito, imprima un registro de que el análisis falló.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Agregue un bloque catch{} para manejar la situación de un archivo de estilo faltante. En el bloque de catch , si el archivo no se puede cargar, lanza una excepción Resources.NotFoundException .
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

El método terminado debería verse como el siguiente fragmento de código:

private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )

       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}
  1. Finalmente, llame al método setMapStyle() en el método onMapReady() pasando su objeto GoogleMap .
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Ejecute su aplicación.
  2. Configure el mapa en modo normal y el nuevo estilo debería ser visible con temas retro y carreteras del color elegido.

b59d6cb81f02a14f.png

Paso 3: estiliza tu marcador

Puede personalizar aún más su mapa aplicando estilo a los marcadores del mapa. En este paso, cambia los marcadores rojos predeterminados por algo más maravilloso.

  1. En el método onMapLongClick() , agregue la siguiente línea de código a MarkerOptions() del constructor para usar el marcador predeterminado, pero cambie el color a azul.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

Ahora onMapLongClickListener() ve así:

map.setOnMapLongClickListener { latLng ->
   // A snippet is additional text that's displayed after the title.
   val snippet = String.format(
       Locale.getDefault(),
       "Lat: %1$.5f, Long: %2$.5f",
       latLng.latitude,
       latLng.longitude
   )
   map.addMarker(
       MarkerOptions()
           .position(latLng)
           .title(getString(R.string.dropped_pin))
           .snippet(snippet)
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
   )
}
  1. Ejecute la aplicación. Los marcadores que aparecen después de un clic prolongado ahora están sombreados en azul. Tenga en cuenta que los marcadores de PDI siguen siendo rojos porque no agregó estilo al método onPoiClick() .

b9916bca3c367e3.png

Una forma de personalizar el mapa de Google es dibujando sobre él. Esta técnica es útil si desea resaltar un tipo particular de ubicación, como lugares de pesca populares.

  • Formas: puede agregar polilíneas , polígonos y círculos al mapa.
  • 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 están orientadas a la superficie de la Tierra en lugar de a la pantalla. Girar, inclinar o hacer zoom en el mapa cambia la orientación de la imagen. Las superposiciones de suelo son útiles cuando desea fijar una sola imagen en un área del mapa.

Paso: agregar una superposición de suelo

En esta tarea, agrega una superposición de suelo en forma de Android a la ubicación de su casa.

  1. Descarga esta imagen de Android y guárdala en tu carpeta res/drawable . (Asegúrese de que el nombre del archivo sea android.png ).

61fabd56a0841b44.png

  1. En onMapReady() , después de la llamada para mover la cámara a la posición de su hogar, cree un objeto GroundOverlayOptions .
  2. Asigne el objeto a una variable llamada androidOverlay .
val androidOverlay = GroundOverlayOptions()
  1. Utilice el método BitmapDescriptorFactory.fromResource() para crear un objeto BitmapDescriptor partir del recurso de imagen descargado.
  2. Pase el objeto BitmapDescriptor resultante al método image() del objeto GroundOverlayOptions .
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Cree un float overlaySize de float overlaySize para el ancho en metros de la superposición deseada. Para este ejemplo, un ancho de 100f funciona bien.

Establezca la propiedad de position para el objeto GroundOverlayOptions llamando al método position() y pase el objeto homeLatLng y overlaySize .

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Llame a addGroundOverlay() en el objeto GoogleMap y pase su objeto GroundOverlayOptions .
map.addGroundOverlay(androidOverlay)
  1. Ejecute la aplicación.
  2. Cambie el valor de zoomLevel a zoomLevel para ver la imagen de Android como una superposición.

b1b25b0acd6a9807.png

Los usuarios suelen utilizar Google Maps para ver su ubicación actual. Para mostrar la ubicación del dispositivo en su mapa, puede usar la capa de datos de ubicación .

La capa de datos de ubicación agrega el icono Mi ubicación al mapa.

f317f84dcb3ac3a1.png

Cuando el usuario toca 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á parado y como un cheurón azul si el dispositivo está en movimiento.

En esta tarea, habilita la capa de datos de ubicación.

Paso: solicitar permisos de ubicación

Habilitar el seguimiento de la ubicación en Google Maps requiere una sola línea de código. Sin embargo, debe asegurarse de que el usuario haya otorgado permisos de ubicación (utilizando el modelo de permiso de tiempo de ejecución).

En este paso, solicita permisos de ubicación y habilita el seguimiento de ubicación.

  1. En el archivo AndroidManifest.xml , verifique que el permiso FINE_LOCATION ya esté presente. Android Studio insertó este permiso cuando seleccionó la plantilla de Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. En MapsActivity , cree una variable de clase REQUEST_LOCATION_PERMISSION .
private val REQUEST_LOCATION_PERMISSION = 1
  1. Para verificar si se otorgan permisos, cree un método en MapsActivity llamado isPermissionGranted() . En este método, verifique si el usuario ha otorgado el permiso.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Para habilitar el seguimiento de la ubicación en su aplicación, cree un método en MapsActivity llamado enableMyLocation() que no tome argumentos y no devuelva nada. En el interior, compruebe el permiso ACCESS_FINE_LOCATION . Si se concede el permiso, habilite la capa de ubicación. De lo contrario, solicite el permiso.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Llame a enableMyLocation() desde la devolución de llamada onMapReady() para habilitar la capa de ubicación.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. onRequestPermissionsResult() método onRequestPermissionsResult() . Compruebe si el requestCode es igual a REQUEST_LOCATION_PERMISSION . Si es así, significa que se concede el permiso. Si se concede el permiso, también verifique si la matriz grantResults contiene PackageManager.PERMISSION_GRANTED en su primera ranura. Si eso es cierto, llame a enableMyLocation() .
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Ejecute su aplicación. Debería haber un cuadro de diálogo solicitando acceso a la ubicación del dispositivo. Adelante, dé permiso.

da7e23e00ec762c1.png

El mapa ahora muestra la ubicación actual del dispositivo con un punto azul. Observe que hay un botón de ubicación. Si aleja el mapa de su ubicación y hace clic en este botón, vuelve a centrar el mapa en la ubicación del dispositivo.

5b12eda7f467bc2f.png

Descargue el código para el codelab terminado.

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps

Alternativamente, puede descargar el repositorio como un archivo zip, descomprimirlo y abrirlo en Android Studio.

Descargar zip

¡Felicidades! Agregó un mapa de Google a una aplicación de Android Kotlin y le dio estilo.

Documentación para desarrolladores de Android:

Documentación de referencia:

Para obtener enlaces a otros laboratorios de código de este curso, consulte la página de inicio de los laboratorios de código de Android avanzado en Kotlin .