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

Este codelab faz parte do curso Android avançado no Kotlin. Você aproveitará mais o 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 avançados do Android em Kotlin (link em inglês).

A criação de aplicativos com o Google Maps permite que você adicione recursos ao seu aplicativo, como imagens de satélite, controles robustos de IU para mapas, rastreamento de locais e marcadores de localização. 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 para pesca ou escalada. São jogos em que o jogador explora o mundo físico, como uma caça ao tesouro ou jogos de realidade aumentada.

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

Prerequisites

Conhecimento sobre os seguintes itens:

  • 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 receber uma chave de API no Console de APIs do Google e registrá-la no seu app
  • Como integrar um mapa do Google Maps ao seu app
  • Como exibir diferentes tipos de mapa
  • Como estilizar o mapa do Google Maps
  • Como adicionar marcadores ao mapa
  • Como permitir que o usuário posicione 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 estilo
  • Como ativar o monitoramento de local no seu app

Neste codelab, você criará o app Wander, que exibe um mapa do Google com estilos personalizados. O app Wander permite colocar marcadores em locais, adicionar sobreposições e ver a localização em tempo real.

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

Neste codelab, você usará a chave de API para o certificado de depuração. Por padrão, o certificado de depuração não é seguro, como 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 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 que contém um link que simplifica a geração de uma chave de API.

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

  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 Finish.
  4. Quando o processo de criação do app for concluído, confira seu projeto e os seguintes arquivos relacionados a mapas que o Android Studio criará:

google_maps_api.xml: você usa esse arquivo de configuração para manter 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á 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ê usará apenas o certificado de depuração.

activity_maps.xml: este arquivo de layout contém um único fragmento que preenche toda a tela. A classe SupportMapFragment é uma subclasse da Fragment. SupportMapFragment é a forma mais simples de inserir um mapa em um app. Ele é um wrapper em torno da visualização de um mapa para atender automaticamente às necessidades necessárias do ciclo de vida.

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

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

MapsActivity.java: o arquivo MapsActivity.kt instancia o SupportMapFragment no método onCreate() e usa a classe 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: obter 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 de URL incluem informações específicas sobre o app.
  3. Copie e cole o URL em um navegador.
  4. Siga as instruções para criar um projeto na página "Serviços e APIs". Devido aos parâmetros do URL fornecido, a página sabe 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 aos 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 onde está escrito YOUR_KEY_HERE.
  10. Execute o app. Você verá um mapa incorporado na sua atividade com um marcador definido em Sydney, Austrália. O marcador de Sydney é parte do modelo e você o alterará posteriormente.

Etapa 3: renomear o mMap

MapsActivity tem uma lateinit var particular chamada 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 "none" (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 a navegação em um carro, é útil ver os nomes das ruas para que você possa usar a opção normal. Durante as caminhadas, o mapa de terreno pode ser útil para decidir o quanto você precisa subir para chegar ao topo.

Nesta tarefa, você:

  1. Adicione uma barra de apps com um menu de opções para o usuário mudar o tipo de mapa.
  2. Mover o local de partida do mapa para o local da sua casa.
  3. Adição de suporte a marcadores, que indicam locais únicos em um mapa e podem incluir uma etiqueta.

Adicionar menu para tipos de mapa

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

  1. Para criar um novo arquivo XML do menu, clique com o botão direito 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 como o tipo de recurso.
  4. Clique em OK.
  5. Na guia Código, substitua o código no novo arquivo pelo código abaixo para criar as opções do menu de mapa. O tipo de mapa "none" é omitido porque "none" resulta na falta de qualquer mapa. Esta etapa causa um erro, mas você o resolverá na próxima.
<?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 para os 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. No MapsActivity, substitua o método onCreateOptionsMenu() e infle o menu do arquivo de recursos map_options.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. No MapsActivity.kt, substitua o método onOptionsItemSelected(). Altere o tipo de mapa usando as 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 alterar 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 deslocar para Sydney.

Nesta tarefa, você moverá a câmera do mapa para sua casa, aumentará o zoom até um nível especificado e colocará um marcador nela.

Etapa 1: aplicar zoom na 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 mova a câmera. O método ficará assim:
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 aumentar o zoom no mapa. Use o nível de zoom 15f.
val zoomLevel = 15f

O nível de zoom controla o zoom no mapa. A lista a seguir oferece uma ideia do nível de detalhamento de cada nível de zoom:

  • 1: mundo
  • 5: terra/continente
  • 10: cidade
  • 15: ruas
  • 20: edifícios
  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 a 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 se moverá até a 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ê adicionará um marcador quando o usuário tocar em um local no mapa e o segurar.

  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 do mapa.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. No método setOnMapLongClickListener(), chame o método addMarker(). Transmita um novo objeto MarkerOptions com a posição definida para 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 mantenha pressionado o mapa para colocar um marcador em um local.
  3. Toque no marcador, que será centralizado na tela.

Etapa 3: adicione uma janela de informações para o marcador

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

  1. Em setMapLongClick()setOnMapLongClickListener(), crie um val para snippet. 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. No addMarker(), defina o title do marcador como Eliminado alfinete 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 colocar um marcador de local.
  3. Toque no marcador para mostrar a janela de informações.

Etapa 4: adicionar o listener de PDIs

Por padrão, os pontos de interesse (PDIs) aparecem no mapa com os ícones correspondentes. Esses pontos 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 empresas, como lojas, restaurantes e hotéis.

Nesta etapa, você 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 contendo 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. Na 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() em poiMarker para mostrar imediatamente a janela de informações.
poiMarker.showInfoWindow()

O código final da 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 do método 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 café.
  2. Toque em um PDI para colocar um marcador nele e exibir o nome do PDI em uma janela de informações.

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

É possível personalizar um objeto MapFragment usando os atributos XML disponíveis, como você faria com qualquer outro fragmento. No entanto, nesta etapa, você personalizará 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 especifique como os recursos no mapa serão exibidos. Não é preciso criar esse arquivo JSON manualmente. O Google fornece o assistente de estilo da Plataforma Google Maps, que gera o JSON depois de definir o estilo do mapa. Nesta tarefa, você estiliza o mapa com um tema retrô, o que significa que ele usa cores vintage e você adiciona 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 Estrada > Preenchimento.
  2. Altere a cor das estradas para a cor escolhida, como rosa.

  1. Clique em Finish.

  1. Copie o código JSON da caixa de diálogo exibida e, se quiser, guarde-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. Use os recursos do diretório raw, como o código JSON.
  2. Crie um arquivo no res/raw chamado map_style.json.
  3. Cole o código JSON oculto no novo arquivo de recursos.
  4. No 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 no MapsActivity, crie uma função setMapStyle() que use um GoogleMap.
  2. Em setMapStyle(), adicione um bloco try{}.
  3. No bloco try{}, crie uma val success para aplicar o estilo. O bloco de captura a seguir é adicionado.
  4. No bloco try{}, defina o estilo JSON no 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 configuraçã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. Adição de uma instrução "if" para success como "false". Se o estilo não for bem-sucedido, exiba um registro de 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 ficará assim:

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. Defina o mapa para o modo normal. O novo estilo ficará visível com temas retrô e vias da cor escolhida.

Etapa 3: definir o estilo do marcador

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

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

Agora, onMapLongClickListener() 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. Agora os marcadores que aparecem após um clique longo ficam azuis. Os marcadores de PDIs ainda estão vermelhos porque você não adicionou um estilo ao método onPoiClick().

Um modo de personalizar o mapa do Google é desenhando sobre ele. Essa técnica é útil para destacar um tipo específico de local, como pontos de pesca famosos.

  • Formas: você pode adicionar polilinhas, polígonos e círculos ao mapa.
  • Objetos GroundOverlay: uma sobreposição de solo é uma imagem 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. Elas são úteis quando você quer corrigir uma única imagem em uma área.

Etapa: adicionar uma sobreposição de solo

Nesta tarefa, você adicionará uma sobreposição de solo no formato de um Android ao local da sua casa.

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

  1. Em 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 chamada androidOverlay.
val androidOverlay = GroundOverlayOptions()
  1. Use o método BitmapDescriptorFactory.fromResource() para criar um objeto BitmapDescriptor com base no recurso de imagem salvo.
  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, a largura da 100f funciona bem.

Defina a propriedade position para o objeto GroundOverlayOptions chamando o método position() e transmita o objeto homeLatLng e a 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.

Muitas vezes, os usuários usam o Google Maps para ver seu local atual. Para exibir o local do dispositivo no seu 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 centraliza na localização do dispositivo. A localização será mostrada como um ponto azul se o dispositivo estiver parado e como uma divisa azul se o dispositivo estiver em movimento.

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

Etapa: solicitar permissões de localização

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

Nesta etapa, você solicita permissões de localização e ativa o rastreamento 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 no 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 no MapsActivity chamado enableMyLocation(), que não aceite argumentos e não retorne nada. Dentro dela, verifique a permissão ACCESS_FINE_LOCATION. Se a permissão for concedida, ative a camada de local. 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 local.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. Modifique o método onRequestPermissionsResult(). Se requestCode for igual a REQUEST_LOCATION_PERMISSION, a permissão será concedida, e 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. É preciso haver uma caixa de diálogo solicitando acesso à localização do dispositivo. Conceda permissão.

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

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

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


Também é possível fazer o download do repositório como um arquivo ZIP, descompactá-lo e abri-lo 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, o uso do modelo de atividades 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 uma GoogleMap no momento da execução, use o método GoogleMap.setMapType(). Um mapa do Google Maps pode ser um dos seguintes tipos:

  • Normal: mapa de vias 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. Marcadores de estradas e de elementos 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 tocado, o comportamento padrão do marcador é exibir uma janela com informações 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) são exibidos por padrão no mapa quando o tipo dele é normal.
  • É possível capturar cliques em PDIs usando o método OnPoiClickListener.
  • Você pode alterar a aparência de quase todos os elementos de um mapa do Google Maps usando o Assistente de estilo. O Assistente de estilo gera um arquivo JSON que você transmite ao mapa usando o método setMapStyle().
  • Você pode personalizar seus marcadores mudando a cor padrão ou substituindo o ícone do marcador padrão por uma imagem personalizada.

Outras informações importantes:

  • Use uma sobreposição de solo para corrigir uma imagem em uma localização geográfica.
  • Use um objeto GroundOverlayOptions para especificar a imagem, o tamanho dela em metros e a posição dela. Transmita esse objeto ao método GoogleMap.addGroundOverlay() para definir a sobreposição no mapa.
  • Desde que seu app tenha a permissão ACCESS_FINE_LOCATION, é possível ativar o rastreamento de localização definindo map.isMyLocationEnabled = true.
  • Ela não é abordada neste codelab, mas é possível fornecer informações adicionais sobre um local usando o Google Street View, que é uma foto navegável de panorama de um determinado local.

Documentação do desenvolvedor Android:

Documentação de referência:

Para ver links de outros codelabs deste curso, consulte a página de destino sobre os codelabs avançados do Android em Kotlin (link em inglês).