Android avançado no Kotlin 04.1: Google Maps no Android

1. Antes de começar

Criar aplicativos com o Google Maps permite adicionar recursos ao aplicativo, como imagens de satélite, controles de IU robustos para mapas, rastreamento de localização e marcadores de local. Você pode agregar valor ao Google Maps padrão, mostrando informações do seu próprio conjunto de dados, como os locais de áreas conhecidas de pesca ou escalada. Também é possível criar jogos em que o jogador explora o mundo físico, como em uma caça ao tesouro ou até mesmo em jogos de realidade aumentada.

Nesta lição, você vai criar um app do Google Maps chamado Wander que mostra mapas personalizados e a localização do usuário.

Pré-requisitos

Conhecimento sobre:

  • Como criar um app Android básico e executá-lo usando o Android Studio.
  • Como criar e gerenciar recursos, como strings.
  • Como refatorar o código e renomear variáveis usando o Android Studio.
  • Como usar um mapa do Google como usuário.
  • Como definir permissões de execução.

O que você vai aprender

  • Como gerar uma chave de API no Console de APIs do Google e registrar a chave no seu app
  • Como integrar um mapa do Google ao seu app
  • Como exibir diferentes tipos de mapa
  • Como estilizar o mapa do Google
  • Como adicionar marcadores ao mapa
  • Como permitir que o usuário coloque um marcador em um ponto de interesse (PDI)
  • Como ativar o rastreamento de localização
  • Como criar o app Wander, que tem um mapa do Google Maps incorporado.
  • Como criar recursos personalizados para o app, como marcadores e estilo.
  • Como ativar o rastreamento de localização no seu app

2. Visão geral do app

Neste codelab, você vai criar o app Wander, que mostra um mapa do Google com estilização personalizada. O app Wander permite que você coloque marcadores em locais, adicione sobreposições e veja seu local em tempo real.

5b12eda7f467bc2f.png

3. Tarefa: configurar o projeto e gerar uma chave de API

O SDK do Maps para Android requer uma chave de API. Para obter a chave de API, registre seu projeto na página API & Serviços. A chave de API está vinculada a um certificado digital que vincula o app ao autor. Para mais informações sobre como usar certificados digitais e assinar seu app, consulte Assinar o app.

Neste codelab, você vai usar a chave de API para o certificado de depuração. O certificado de depuração não é seguro por padrão, conforme descrito em Assinar o build de depuração. Os apps Android publicados que usam o SDK do Maps para Android exigem uma segunda chave de API: a chave do certificado de lançamento. Para mais informações sobre como acessar um certificado de lançamento, consulte Acessar uma chave de API.

O Android Studio inclui um modelo Google Maps Activity, que gera um código de modelo útil. O código do modelo inclui um arquivo google_maps_api.xml com um link que simplifica a obtenção de uma chave de API.

Etapa 1: criar o projeto Wander com o modelo do Maps

  1. Crie um novo projeto do Android Studio.
  2. Selecione o modelo Google Maps Activity.

d6b874bb19ea68cd.png

  1. Nomeie o projeto como Wander.
  2. Defina o nível mínimo da API como API 19. Confira se a linguagem é Kotlin.
  3. Clique em Finish.
  4. Quando a criação do app for concluída, confira seu projeto e os seguintes arquivos relacionados a mapas que o Android Studio cria para você:

google_maps_api.xml: use esse arquivo de configuração para armazenar sua chave de API. O modelo gera dois arquivos google_maps_api.xml: um para depuração e outro para lançamento. O arquivo da chave de API do certificado de depuração está localizado em src/debug/res/values. O arquivo da chave de API do certificado de lançamento está localizado em src/release/res/values. Neste codelab, você vai usar apenas o certificado de depuração.

activity_maps.xml: arquivo de layout contém um único fragmento que preenche toda a tela. A classe SupportMapFragment é uma subclasse da Fragment. Uma SupportMapFragment é a maneira mais simples de inserir um mapa em um app. É um wrapper em torno da visualização de um mapa para lidar automaticamente com as necessidades necessárias do ciclo de vida.

Você pode incluir SupportMapFragment em um arquivo de layout usando uma tag <fragment> em qualquer ViewGroup, com um atributo name extra.

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

MapsActivity.java: o arquivo MapsActivity.java instancia o SupportMapFragment no método onCreate() e usa o objeto getMapAsync() para inicializar automaticamente o sistema de mapas e a visualização. A atividade que contém o SupportMapFragment precisa implementar a interface OnMapReadyCallback e o método onMapReady() dessa interface. O método onMapReady() é chamado quando o mapa é carregado.

Etapa 2: conseguir a chave de API

  1. Abra a versão de depuração do arquivo google_maps_api.xml.
  2. No arquivo, procure um comentário com um URL longo. Os parâmetros do URL incluem informações específicas sobre seu app.
  3. Copie e cole o URL em um navegador.
  4. Siga as instruções para criar um projeto na página APIs e Serviços. Devido aos parâmetros no URL fornecido, a página sabe que deve ativar automaticamente o SDK do Maps para Android.
  5. Clique em Criar uma chave de API.
  6. Na próxima página, vá para a seção "Chaves de API" e clique na chave que você acabou de criar.
  7. Clique em Restringir chave e selecione SDK do Maps para Android para restringir o uso da chave a apps Android.
  8. Copie a chave de API gerada. Começa com "AIza".
  9. No arquivo google_maps_api.xml, cole a chave na string google_maps_key em que diz YOUR_KEY_HERE.
  10. Execute o app. Você verá um mapa incorporado à sua atividade com um conjunto de marcadores em Sydney, Austrália. O marcador de Sydney faz parte do modelo e você pode alterá-lo depois.

34dc9dd877c90996.png

Etapa 3: renomear o mMap

MapsActivity tem um var lateinit particular chamado mMap, que é do tipo GoogleMap. Para seguir as convenções de nomenclatura do Kotlin, mude o nome de mMap para map.

  1. Em MapsActivity, clique com o botão direito do mouse em mMap e clique em Refatorar > Renomear...

e713ccb3384450c6.png

  1. Mude o nome da variável para map.

Todas as referências a mMap na função onMapReady() também mudam para map.

4. Tarefa: adicionar tipos de mapa

O Google Maps inclui vários tipos de mapa: normal, híbrido, satélite, terreno e "nenhum" (para nenhum mapa).

Mapa normal

Mapa de satélite

Mapa híbrido

Mapa de terreno

Cada tipo de mapa fornece diferentes tipos de informações. Por exemplo, ao usar mapas para navegação em um carro, é útil ver os nomes das ruas, para poder usar a opção "Normal". Quando você está caminhando, o mapa de terreno pode ser útil para decidir o quanto é preciso escalar para chegar ao topo.

Nesta tarefa, você vai:

  1. Adicione uma barra de apps com um menu de opções que permita ao usuário alterar o tipo de mapa.
  2. Mova o local de partida do mapa para sua própria casa.
  3. Adicione suporte para marcadores, que indicam locais únicos em um mapa e podem incluir um rótulo.

Adicionar menu para tipos de mapa

Nesta etapa, você vai adicionar uma barra de apps com um menu de opções que permite ao usuário mudar o tipo de mapa.

  1. Para criar um novo arquivo XML de menu, clique com o botão direito do mouse no diretório res e selecione New > Arquivo de recursos do Android.
  2. Na caixa de diálogo, nomeie o arquivo map_options.
  3. Escolha Menu como o tipo de recurso.
  4. Clique em OK.
  5. Na guia Código, substitua o código no novo arquivo pelo seguinte para criar as opções de menu do mapa. O argumento "nenhum" tipo de mapa é omitido porque "nenhum" resulta na ausência de qualquer mapa. Esta etapa causa um erro, mas você vai resolvê-lo na próxima etapa.
<?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. No strings.xml, adicione recursos aos atributos title para resolver os erros.
<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. Em MapsActivity, modifique o método onCreateOptionsMenu() e infle o menu do arquivo de recurso map_options.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. No MapsActivity.kt, modifique o método onOptionsItemSelected(). Altere o tipo de mapa usando constantes de tipo de mapa para refletir a seleção do usuário.
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. Execute o app.
  2. Clique em 428da163b831115b.png para alterar o tipo de mapa. Observe como a aparência do mapa muda entre os diferentes modos.

6fa42970d87f5dc7.png

5. Tarefa: adicionar marcadores

Por padrão, o callback onMapReady() inclui o código que coloca um marcador em Sydney, Austrália, onde o Google Maps foi criado. O callback padrão também anima o mapa para se deslocar até Sydney.

Nesta tarefa, você vai mover a câmera do mapa até sua casa, aplicar zoom no nível especificado e colocar um marcador nesse local.

Etapa 1: aplique o zoom na sua casa e adicione um marcador

  1. No arquivo MapsActivity.kt, encontre o método onMapReady(). Remova o código que coloca o marcador em Sydney e move a câmera. Seu método ficará assim agora.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Encontre a latitude e a longitude da sua casa seguindo estas instruções.
  2. Crie um valor para a latitude e um para a longitude e insira os valores de flutuação.
val latitude = 37.422160
val longitude = -122.084270
  1. Crie um novo objeto LatLng com o nome homeLatLng. No objeto homeLatLng, transmita os valores que você acabou de criar.
val homeLatLng = LatLng(latitude, longitude)
  1. Crie uma val para definir o nível de zoom que você quer para o mapa. Use o nível de zoom 15f.
val zoomLevel = 15f

O nível de zoom controla o quanto você gostaria de aumentar o zoom do mapa. A lista a seguir dá uma ideia do nível de detalhe que cada nível de zoom mostra:

  • 1: mundo
  • 5: terra/continente
  • 10: cidade
  • 15: ruas
  • 20: construções
  1. Mova a câmera para homeLatLng chamando a função moveCamera() no objeto map e transmita um objeto CameraUpdate usando CameraUpdateFactory.newLatLngZoom(). Transmita o objeto homeLatLng e o zoomLevel.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. Adicione um marcador ao mapa em homeLatLng.
map.addMarker(MarkerOptions().position(homeLatLng))

O método final vai ficar assim:

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. Execute o app. O mapa deve se movimentar até a casa, aplicar zoom no nível desejado e colocar um marcador na casa.

fc939024778ee76.png

Etapa 2: permitir que os usuários adicionem um marcador usando um clique longo

Nesta etapa, você vai adicionar um marcador quando o usuário tocar e mantiver um local no mapa.

  1. Crie um stub de método em MapsActivity com o nome setMapLongClick(), que usa um GoogleMap como argumento.
  2. Anexe um listener setOnMapLongClickListener ao objeto "map".
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. Em setOnMapLongClickListener(), chame o método addMarker(). Transmita um novo objeto MarkerOptions com a posição definida como o LatLng transmitido.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. No final do método onMapReady(), chame setMapLongClick() com map.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. Execute o app.
  2. Toque no mapa e mantenha-o pressionado para colocar um marcador em um local.
  3. Toque no marcador, que o centraliza na tela.

4ff8d1c1db3bca9e.png

Etapa 3: adicionar uma janela de informações ao marcador

Nesta etapa, você vai adicionar uma InfoWindow que vai mostrar as coordenadas do marcador quando ele for tocado.

  1. Em setMapLongClick()setOnMapLongClickListener(), crie uma val para a snippet. Um snippet é um texto adicional exibido após o título. Seu snippet exibe a latitude e a longitude de um 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. Em addMarker(), defina o title do marcador como Pin inserido usando um recurso de string R.string.dropped_pin.
  2. Defina o snippet do marcador como snippet.

A função concluída fica assim:

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. Execute o app.
  2. Toque no mapa e mantenha-o pressionado para inserir um marcador de local.
  3. Toque no marcador para mostrar a janela de informações.

63f210e6e47dfa29.png

Etapa 4: adicionar um listener de PDI

Por padrão, os pontos de interesse (PDIs) aparecem no mapa com seus respectivos ícones. Os PDIs incluem parques, escolas, edifícios governamentais e muito mais. Quando o tipo de mapa é definido como normal, os PDIs de empresas também aparecem no mapa. Os PDIs de empresas representam estabelecimentos como lojas, restaurantes e hotéis.

Nesta etapa, você vai adicionar uma GoogleMap.OnPoiClickListener ao mapa. Esse listener de clique coloca um marcador no mapa imediatamente quando o usuário clica em um PDI. O listener de clique também exibe uma janela de informações com o nome do PDI.

  1. Crie um stub de método em MapsActivity com o nome setPoiClick(), que usa um GoogleMap como argumento.
  2. No método setPoiClick(), defina um OnPoiClickListener no GoogleMap transmitido.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. No setOnPoiClickListener(), crie um val poiMarker para o marcador .
  2. Defina-o como um marcador usando map.addMarker(), com MarkerOptions, definindo title como o nome do PDI.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. Na função setOnPoiClickListener(), chame showInfoWindow() na poiMarker para mostrar imediatamente a janela de informações.
poiMarker.showInfoWindow()

O código final para a função setPoiClick() ficará assim.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. No final de onMapReady(), chame setPoiClick() e transmita map.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. Execute o app e encontre um PDI, como um parque ou uma cafeteria.
  2. Toque no PDI para inserir um marcador e exibir o nome dele em uma janela de informações.

f4b0972c75d5fa5f.png

6. Tarefa: personalizar seu mapa

Você pode personalizar o Google Maps de várias maneiras, proporcionando uma aparência única ao seu mapa.

É possível personalizar um objeto MapFragment usando os atributos XML disponíveis, da mesma forma que você personalizaria qualquer outro fragmento. No entanto, nesta etapa, você vai personalizar a aparência do conteúdo da MapFragment usando métodos no objeto GoogleMap.

Para criar um estilo personalizado para seu mapa, gere um arquivo JSON que especifique como os elementos do mapa são exibidos. Não é necessário criar esse arquivo JSON manualmente. O Google oferece o assistente de estilo da Plataforma Google Maps, que gera o JSON depois que você estiliza seu mapa visualmente. Nesta tarefa, você estiliza o mapa com um tema retrô, o que significa que o mapa usa cores vintage, e você adiciona vias coloridas.

Etapa 1: criar um estilo para o mapa

  1. Acesse https://mapstyle.withgoogle.com/ no seu navegador.
  2. Selecione Criar um estilo.
  3. Selecione Retrô.

208b3d3aeab0d9b6.png

  1. Clique em Mais opções.

4a35faaf9535ee82.png

  1. Selecione Via > Preenchimento.
  2. Mude a cor das vias para qualquer cor que você quiser (por exemplo, rosa).

92c3293749293a4c.png

  1. Clique em Finish.

f1bfe8585eb69480.png

  1. Copie o código JSON da caixa de diálogo resultante e, se quiser, guarde-o em uma nota de texto simples para usar na próxima etapa.

3c32168b299d6420.png

Etapa 2: adicionar o estilo ao mapa

  1. No diretório res do Android Studio, crie um diretório de recursos com o nome raw. Use os recursos do diretório raw como o código JSON.
  2. Crie um arquivo em res/raw com o nome map_style.json.
  3. Cole seu código JSON guardado no novo arquivo de recursos.
  4. Em MapsActivity, crie uma variável de classe TAG acima do método onCreate(). Isso é usado para fins de registro.
private val TAG = MapsActivity::class.java.simpleName
  1. Ainda em MapsActivity, crie uma função setMapStyle() que use uma GoogleMap.
  2. Em setMapStyle(), adicione um bloco try{}.
  3. No bloco try{}, crie uma val success para o sucesso do estilo. Você adiciona o seguinte bloco catch a seguir.
  4. No bloco try{}, defina o estilo JSON como o mapa e chame setMapStyle() no objeto GoogleMap. Transmita um objeto MapStyleOptions, que carrega o arquivo JSON.
  5. Atribua o resultado a success. O método setMapStyle() retorna um booleano indicando o status de êxito da análise do arquivo de estilo e da definição do 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. Adicione uma instrução if para success ser falsa. Se o estilo não funcionar, gere um registro informando que a análise falhou.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. Adicione um bloco catch{} para processar a situação de um arquivo de estilo ausente. No bloco catch, se o arquivo não puder ser carregado, gere uma Resources.NotFoundException.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

O método finalizado ficará parecido com este snippet 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. Por fim, chame o método setMapStyle() no método onMapReady() transmitindo seu objeto GoogleMap.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Execute o app.
  2. No mapa, use o modo normal. O novo estilo vai ficar visível com temas retrô e vias na cor escolhida.

b59d6cb81f02a14f.png

Etapa 3: definir o estilo do marcador

Para personalizar ainda mais seu mapa, estilize os marcadores dele. Nesta etapa, você vai mudar os marcadores vermelhos padrão para algo mais descolado.

  1. No método onMapLongClick(), adicione a linha de código abaixo ao MarkerOptions() do construtor para usar o marcador padrão, mas mude a cor para azul.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

Agora, o onMapLongClickListener() vai ficar assim:

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. Execute o app. Os marcadores que aparecem depois de um clique longo agora estão sombreados em azul. Os marcadores de PDIs ainda estão vermelhos porque você não adicionou estilo ao método onPoiClick().

b9916bca3c367e3.png

7. Tarefa: adicionar uma sobreposição

Uma maneira de personalizar o mapa do Google é desenhando em cima dele. Essa técnica é útil se você quiser destacar um tipo específico de local, como pontos de pesca populares.

  • Formas: você pode adicionar polilinhas, polígonos e círculos ao mapa.
  • GroundOverlay objetos: uma sobreposição de solo é uma imagem que é fixada em um mapa. Diferentemente dos marcadores, as sobreposições de solo são orientadas para a superfície da Terra e não para a tela. Girar, inclinar ou alterar o zoom do mapa altera a orientação da imagem. As sobreposições de solo são úteis quando você quer corrigir uma única imagem em uma área do mapa.

Etapa: adicionar uma sobreposição de solo

Nesta tarefa, você vai adicionar ao local da sua casa uma sobreposição de solo na forma de um dispositivo Android.

  1. Baixe esta imagem do Android e salve-a na pasta res/drawable. Verifique se o nome do arquivo é android.png.

61fabd56a0841b44.png

  1. No onMapReady(), após a chamada para mover a câmera para a posição da sua casa, crie um objeto GroundOverlayOptions.
  2. Atribua o objeto a uma variável com o nome androidOverlay.
val androidOverlay = GroundOverlayOptions()
  1. Use o método BitmapDescriptorFactory.fromResource() para criar um objeto BitmapDescriptor com base no recurso de imagem transferido por download.
  2. Transmita o objeto BitmapDescriptor resultante para o método image() do objeto GroundOverlayOptions.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. Crie um float overlaySize para a largura em metros da sobreposição desejada. Para este exemplo, uma largura de 100f funciona bem.

Defina a propriedade position para o objeto GroundOverlayOptions chamando o método position() e transmita o objeto homeLatLng e o overlaySize.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. Chame addGroundOverlay() no objeto GoogleMap e transmita o objeto GroundOverlayOptions.
map.addGroundOverlay(androidOverlay)
  1. Execute o app.
  2. Mude o valor de zoomLevel para 18f para mostrar a imagem do Android como uma sobreposição.

b1b25b0acd6a9807.png

8. Tarefa: ativar o rastreamento de localização

Os usuários costumam usar o Google Maps para saber onde estão. Para mostrar o local do dispositivo no seu mapa, use a camada de dados de local.

A camada de dados de local adiciona o ícone Meu local ao mapa.

f317f84dcb3ac3a1.png

Quando o usuário toca no botão, o mapa centraliza a localização do dispositivo. O local será mostrado como um ponto azul se o dispositivo estiver parado e como uma seta azul se ele estiver em movimento.

Nesta tarefa, você vai ativar a camada de dados de local.

Etapa: solicitar permissões de localização

A ativação do rastreamento de localização no Google Maps requer uma única linha de código. No entanto, você precisa garantir que o usuário tenha concedido permissões de localização (usando o modelo de permissão de execução).

Nesta etapa, você vai solicitar permissões de localização e ativar o rastreamento.

  1. No arquivo AndroidManifest.xml, verifique se a permissão FINE_LOCATION já está presente. O Android Studio inseriu essa permissão quando você selecionou o modelo do Google Maps.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. Em MapsActivity, crie uma variável de classe REQUEST_LOCATION_PERMISSION.
private val REQUEST_LOCATION_PERMISSION = 1
  1. Para verificar se as permissões foram concedidas, crie um método na MapsActivity chamado isPermissionGranted(). Nesse método, verifique se o usuário concedeu a permissão.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. Para ativar o acompanhamento de local no seu app, crie um método no MapsActivity com o nome enableMyLocation(), que não usa argumentos e não retorna nada. Dentro dela, verifique a permissão ACCESS_FINE_LOCATION. Se a permissão for concedida, ative a camada de localização. Caso contrário, solicite a permissão.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. Chame enableMyLocation() do callback onMapReady() para ativar a camada de localização.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Modifique o método onRequestPermissionsResult(). Confira se requestCode é igual a REQUEST_LOCATION_PERMISSION. Se for, a permissão foi concedida. Se a permissão for concedida, verifique também se a matriz grantResults contém PackageManager.PERMISSION_GRANTED no primeiro slot. Se isso for verdadeiro, chame enableMyLocation().
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. Execute o app. Deve haver uma caixa de diálogo solicitando acesso à localização do dispositivo. Dê permissão.

da7e23e00ec762c1.png

O mapa agora mostra a localização atual do dispositivo usando um ponto azul. Observe que há um botão de localização. Se você afastar o mapa de seu local e clicar nesse botão, ele centralizará o mapa de volta no local do dispositivo.

5b12eda7f467bc2f.png

9. Código da solução

Faça o download do código do codelab concluído.

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

Se preferir, você pode fazer o download do repositório como um arquivo ZIP, descompactar e abrir no Android Studio.

10. Resumo

Parabéns! Você adicionou um mapa do Google a um app Android em Kotlin e o definiu.

11. Saiba mais

Documentação do desenvolvedor Android:

Documentação de referência:

12. Próximo codelab

Para acessar links de outros codelabs deste curso, consulte a página de destino dos codelabs avançados do Android no Kotlin.