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

Este codelab faz parte do curso Android avançado no Kotlin. Você vai aproveitar mais este curso se fizer os codelabs em sequência, mas isso não é obrigatório. Todos os codelabs do curso estão listados na página de destino dos codelabs do Android avançado em Kotlin.

Ao criar apps com o Google Maps, você pode adicionar recursos como imagens de satélite, controles robustos de interface para mapas, rastreamento e marcadores de localização. Você pode adicionar valor ao Google Maps padrão mostrando informações do seu próprio conjunto de dados, como os locais de áreas de pesca ou escalada conhecidas. Você também pode criar jogos em que o jogador explora o mundo físico, como uma caça ao tesouro ou até mesmo 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 e executar um app Android básico usando o Android Studio.
  • Como criar e gerenciar recursos, como strings.
  • Como refatorar código e renomear variáveis usando o Android Studio.
  • Como usar um mapa do Google como usuário.
  • Como definir permissões de tempo de execução.

O que você vai aprender

  • Como conseguir uma chave de API no Console de API do Google e registrar a chave no seu app
  • Como integrar um mapa do Google ao seu app
  • Como mostrar diferentes tipos de mapa
  • Como personalizar o estilo do 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 seu app, como marcadores e estilos
  • Como ativar o rastreamento de localização no seu app

Neste codelab, você vai criar o app Wander, que mostra um mapa do Google com estilo personalizado. Com o app Wander, você pode colocar marcadores em locais, adicionar sobreposições e conferir sua localização em tempo real.

O SDK do Maps para Android exige uma chave de API. Para receber a chave de API, registre seu projeto na página "APIs e serviços". A chave de API está vinculada a um certificado digital que associa 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 é inseguro por design, conforme descrito em Assinar sua 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 conseguir um certificado de lançamento, consulte Acessar uma chave de API.

O Android Studio inclui um modelo de atividade do Google Maps, 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 de mapas

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

  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 Concluir.
  4. Depois que o app for criado, confira o projeto e os seguintes arquivos relacionados a mapas que o Android Studio cria para você:

google_maps_api.xml: usado para armazenar a 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 para o 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: esse arquivo de layout contém um único fragmento que preenche toda a tela. A classe SupportMapFragment é uma subclasse da classe Fragment. Um SupportMapFragment é a maneira mais simples de colocar um mapa em um app. Ele é um wrapper em torno de uma visualização de um mapa para processar automaticamente 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 adicional.

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

MapsActivity.java: o arquivo MapsActivity.kt cria uma instância do SupportMapFragment no método onCreate() e usa o getMapAsync() da classe 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: receber 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 como ativar automaticamente o SDK do Maps para Android.
  5. Clique em Criar uma chave de API.
  6. Na próxima página, acesse 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. Ela começa com "AIza".
  9. No arquivo google_maps_api.xml, cole a chave na string google_maps_key onde está escrito YOUR_KEY_HERE.
  10. Execute o app. Você vai ver um mapa incorporado na sua atividade com um marcador definido em Sydney, Austrália. O marcador de Sydney faz parte do modelo, e você pode mudá-lo depois.

Etapa 3: renomear mMap

MapsActivity tem um lateinit var 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 Refactor > Rename...

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

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

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

Mapa normal

Mapa de satélite

Mapa híbrido

Mapa de relevo

Cada tipo de mapa fornece informações diferentes. Por exemplo, ao usar mapas para navegação em um carro, é útil ver os nomes das ruas. Nesse caso, use a opção normal. Ao fazer uma caminhada, o mapa de relevo pode ser útil para decidir quanto mais você precisa subir 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 mudar o tipo de mapa.
  2. Mova o local de partida do mapa para o local da sua 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 > Android Resource File.
  2. Na caixa de diálogo, nomeie o arquivo como map_options.
  3. Escolha Menu para 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 do menu do mapa. O tipo de mapa "none" é omitido porque resulta na ausência de qualquer mapa. Essa etapa causa um erro, mas você vai resolver isso 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. Em strings.xml, adicione recursos para os atributos title e resolva 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, substitua 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. Em MapsActivity.kt, substitua o método onOptionsItemSelected(). Mude 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 para mudar o tipo de mapa. Observe como a aparência do mapa muda entre os diferentes modos.

Por padrão, o callback onMapReady() inclui um 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 fazer uma translação em Sydney.

Nesta tarefa, você vai fazer a câmera do mapa se mover até sua casa, dar zoom até um nível especificado e colocar um marcador lá.

Etapa 1: aumentar o zoom na sua casa e adicionar 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. O método vai ficar assim:
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. Para encontrar a latitude e a longitude da sua casa, siga estas instruções.
  2. Crie um valor para a latitude e outro para a longitude e insira os valores de ponto flutuante.
val latitude = 37.422160
val longitude = -122.084270
  1. Crie um objeto LatLng chamado homeLatLng. No objeto homeLatLng, transmita os valores que você acabou de criar.
val homeLatLng = LatLng(latitude, longitude)
  1. Crie um val para o nível de zoom que você quer usar no mapa. Use o nível de zoom 15f.
val zoomLevel = 15f

O nível de zoom controla o nível de ampliação do mapa. A lista a seguir mostra o nível de detalhamento de cada nível de zoom:

  • 1: Mundo
  • 5: terra/continente
  • 10: Cidade
  • 15: ruas
  • 20: Prédios
  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 vai se mover até sua casa, aumentar o zoom até o nível desejado e colocar um marcador nela.

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

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

  1. Crie um stub de método em MapsActivity chamado setMapLongClick() que receba um GoogleMap como argumento.
  2. Anexe um listener setOnMapLongClickListener ao objeto de mapa.
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 e pressione o mapa para colocar um marcador em um local.
  3. Toque no marcador para centralizá-lo na tela.

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

Nesta etapa, você vai adicionar um InfoWindow que mostra as coordenadas do marcador quando ele é tocado.

  1. Em setMapLongClick()setOnMapLongClickListener(), crie um val para snippet. Um snippet é um texto adicional exibido após o título. O snippet mostra 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 "Pino solto" 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 e mantenha pressionado o mapa para inserir um marcador de local.
  3. Toque no marcador para mostrar a janela de informações.

Etapa 4: adicionar um listener de PDI

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

Nesta etapa, você vai adicionar um 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 mostra uma janela de informações com o nome do PDI.

  1. Crie um stub de método em MapsActivity chamado setPoiClick() que receba 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 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() em poiMarker para mostrar imediatamente a janela de informações.
poiMarker.showInfoWindow()

O código final da função setPoiClick() vai 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 colocar um marcador nele e mostrar o nome do PDI em uma janela de informações.

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

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

Para criar um estilo personalizado para seu mapa, gere um arquivo JSON que especifica como os recursos no mapa são mostrados. Não é necessário criar esse arquivo JSON manualmente. O Google oferece o assistente de estilo da Plataforma Google Maps, que gera o JSON para você depois que você estiliza o mapa visualmente. Nesta tarefa, você vai estilizar o mapa com um tema retrô, ou seja, ele vai usar cores vintage e você vai adicionar vias coloridas.

Etapa 1: criar um estilo para seu mapa

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

  1. Clique em Mais opções.

  1. Na lista Tipo de recurso, selecione Via > Preenchimento.
  2. Mude a cor das vias para qualquer cor que você escolher (como rosa).

  1. Clique em Concluir.

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

Etapa 2: adicionar o estilo ao mapa

  1. No Android Studio, no diretório res , crie um diretório de recursos e nomeie-o como raw. Você usa os recursos do diretório raw como código JSON.
  2. Crie um arquivo em res/raw chamado map_style.json.
  3. Cole o código JSON armazenado 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 receba um GoogleMap.
  2. Em setMapStyle(), adicione um bloco try{}.
  3. No bloco try{}, crie um val success para o sucesso da estilização. (Adicione o seguinte bloco catch.)
  4. No bloco try{}, defina o estilo JSON para 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 sucesso 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 falso. Se o estilo não for bem-sucedido, imprima 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 lidar com a situação de um arquivo de estilo ausente. No bloco catch, se o arquivo não puder ser carregado, gere um 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 vai 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 o objeto GoogleMap.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. Execute o app.
  2. Defina o mapa no modo normal. O novo estilo vai aparecer com o tema retrô e as vias na cor escolhida.

Etapa 3: estilizar o marcador

Você pode personalizar ainda mais o mapa estilizando os marcadores. Nesta etapa, você vai mudar os marcadores vermelhos padrão para algo mais legal.

  1. No método onMapLongClick(), adicione a seguinte linha de código 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().

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

  • Formas:é possível adicionar polilinhas, polígonos e círculos ao mapa.
  • Objetos GroundOverlay:uma sobreposição de solo é uma imagem fixa em um mapa. Ao contrário 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 aumentar o zoom do mapa muda a orientação da imagem. Elas 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 uma sobreposição de solo em forma de Android ao local da sua casa.

  1. Faça o download desta imagem do Android e salve-a na pasta res/drawable. Verifique se o nome do arquivo é android.png.

  1. Em onMapReady(), depois da chamada para mover a câmera até a posição da sua casa, crie um objeto GroundOverlayOptions.
  2. Atribua o objeto a uma variável chamada androidOverlay.
val androidOverlay = GroundOverlayOptions()
  1. Use o método BitmapDescriptorFactory.fromResource() para criar um objeto BitmapDescriptor do recurso de imagem baixado.
  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. Neste 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 ver a imagem do Android como uma sobreposição.

Os usuários costumam usar o Google Maps para ver a localização atual. Para mostrar a localização do dispositivo no mapa, use a camada de dados de localização.

A camada de dados de local adiciona Meu local ao mapa. Quando o usuário toca no botão, o mapa é centralizado no local do dispositivo. A localização é mostrada como um ponto azul se o dispositivo estiver parado e como uma seta azul se estiver em movimento.

Nesta tarefa, você vai ativar a camada de dados de localização.

Etapa: solicitar permissões de localização

Para ativar o rastreamento de local no Google Maps, basta uma linha de código. No entanto, verifique se o usuário concedeu permissões de local (usando o modelo de permissão de tempo de execução).

Nesta etapa, você solicita permissões de localização e ativa o monitoramento de localização.

  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 rastreamento de localização no app, crie um método em MapsActivity chamado 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, peça 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 local.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Modifique o método onRequestPermissionsResult(). Se o requestCode for igual a REQUEST_LOCATION_PERMISSION, a permissão será concedida. Se a matriz grantResults não estiver vazia com PackageManager.PERMISSION_GRANTED no primeiro slot, 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. Uma caixa de diálogo vai pedir acesso à localização do dispositivo. Conceda a permissão.

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

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.

Fazer o download do ZIP

  • Para usar a API Maps, você precisa de uma chave de API do Console de APIs do Google.
  • No Android Studio, usar o modelo de atividade do Google Maps gera um Activity com um único SupportMapFragment no layout do app. O modelo também adiciona o ACCESS_FINE_PERMISSION ao manifesto do app, implementa o OnMapReadyCallback na sua atividade e substitui o método onMapReady() necessário.

Para mudar o tipo de mapa de um GoogleMap durante a execução, use o método GoogleMap.setMapType(). Um mapa do Google pode ser um dos seguintes tipos:

  • Normal: mapa rodoviário típico. Mostra vias, alguns elementos criados pelo homem e recursos naturais importantes, como rios. Marcadores de estradas e de elementos também são visíveis.
  • Híbrido: dados de fotografia de satélite com mapas rodoviários. Marcadores de estradas e de elementos também são visíveis.
  • Satélite: dados de fotografia. Os rótulos de vias e recursos não são visíveis.
  • Relevo: dados topográficos. O mapa inclui cores, curva de nível e marcadores, além de sombreamento de perspectiva. Algumas vias e etiquetas também são visíveis.
  • Nenhum : nenhum bloco de mapa básico.

Sobre o Google Maps:

  • Um marcador é um indicador de um local geográfico específico.
  • Quando alguém toca no marcador, o comportamento padrão é mostrar uma janela de informações com detalhes sobre o local.
  • Por padrão, os pontos de interesse (POIs, na sigla em inglês) aparecem no mapa de base junto com seus respectivos ícones. Esses pontos incluem parques, escolas, edifícios governamentais e muito mais.
  • Além disso, os PDIs de empresas (lojas, restaurantes, hotéis e outros) aparecem por padrão no mapa quando o tipo dele é normal.
  • É possível capturar cliques em PDIs usando o OnPoiClickListener.
  • É possível mudar a aparência visual de quase todos os elementos de um mapa do Google usando o Assistente de estilo. O assistente de estilo gera um arquivo JSON que você transmite para o Google Maps usando o método setMapStyle().
  • Você pode personalizar os marcadores mudando a cor padrão ou substituindo o ícone padrão por uma imagem personalizada.

Outras informações importantes:

  • Use uma sobreposição de solo para fixar uma imagem em um local geográfico.
  • Use um objeto GroundOverlayOptions para especificar a imagem, o tamanho dela em metros e a posição. Transmita esse objeto ao método GoogleMap.addGroundOverlay() para definir a sobreposição no mapa.
  • Desde que o app tenha a permissão ACCESS_FINE_LOCATION, é possível ativar o rastreamento de localização definindo map.isMyLocationEnabled = true.
  • Não vamos abordar isso neste codelab, mas você pode fornecer mais informações sobre um local usando o Google Street View, que é uma foto panorâmica navegável de um determinado local.

Documentação do desenvolvedor Android:

Documentação de referência:

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