Avançado do Android 09.1: Google Maps

1. Olá!

Este codelab faz parte do curso de treinamento Desenvolvimento avançado para Android, desenvolvido pela equipe de treinamento do Google Developers. Você aproveitará mais este curso se fizer os codelabs em sequência.

Para ver todos os detalhes do curso, consulte a Visão geral do Desenvolvimento avançado para Android.

Introdução

A criação de aplicativos com o Google Maps permite adicionar recursos ao aplicativo, como imagens de satélite, controles de IU robustos, 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. Você também pode criar jogos relacionados ao mundo real, como Pokemon Go.

Neste exercício, você vai criar um app do Google Maps chamado Wander.

O que você já precisa saber

Você precisa:

  • Funcionalidade básica do Google Maps.
  • Permissões de execução.
  • Criação, desenvolvimento e execução de apps no Android Studio.
  • Incluir bibliotecas externas no arquivo build.gradle.

O que você vai aprender

  • Integre um mapa do Google ao seu app.
  • Exibir diferentes tipos de mapas.
  • Estilizar o mapa do Google.
  • Adicione marcadores ao mapa.
  • Permita que o usuário coloque um marcador em um ponto de interesse (PDI).
  • Ativar rastreamento de localização.
  • Ativar o Google Street View.

Atividades deste laboratório

  • Acesse uma chave de API no Console de APIs do Google e registre a chave no seu app.
  • Crie o app Wander, que tem um mapa do Google Maps incorporado.
  • Adicione recursos personalizados ao app, como marcadores, estilo e rastreamento de localização.
  • Ativar o rastreamento de local e o Street View no seu app.

2. Visão geral do app

Neste exercício, você vai criar o app Wander, que é um mapa do Google Maps estilizado. O app Wander permite que você coloque marcadores em locais, veja seu local em tempo real e veja panoramas do Street View.

Um mapa do Google estilizado

Google Street View em um app Android

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

A API Google Maps, assim como a API Places, requer uma chave de API. Para conseguir a chave de API, registre seu projeto no Console de APIs do Google. 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 seu app.

Neste exercício, você vai usar a chave de API do 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 aplicativos Android publicados que usam a API Google Maps 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 a 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 o acesso a uma chave de API.

1.1 Criar o projeto Wander com o modelo do Maps

  1. Crie um novo projeto do Android Studio.
  2. Nomeie o novo app como "Wander". Aceite os padrões até acessar a página Adicionar uma atividade.
  3. Selecione o modelo Google Maps Activity.
  4. Mantenha os valores padrão de Activity Name e Layout Name.
  5. Altere o Título para "Passeio". e clique em Concluir.

O Android Studio cria vários arquivos adicionais relacionados a mapas:

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 exercício, usamos 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 Fragment. Você pode incluir SupportMapFragment em um arquivo de layout usando uma tag <fragment> em qualquer ViewGroup, com um atributo adicional:

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

MapsActivity.java

O arquivo MapsActivity.java instancia a classe SupportMapFragment e usa o método getMapAsync() da classe para preparar o mapa do Google Maps. A atividade que contém o SupportMapFragment precisa implementar a interface OnMapReadyCallback e o método onMapReady() dessa interface. O método getMapAsync() retorna um objeto GoogleMap, o que significa que o mapa foi carregado.

1.2 Obter a chave de API

  1. Abra a versão de depuração do arquivo google_maps_api.xml.

O arquivo inclui um comentário com um URL longo. Os parâmetros do URL incluem informações específicas sobre seu app.

  1. Copie e cole o URL em um navegador.
  2. Siga as instruções para criar um projeto no Console de APIs do Google. Devido aos parâmetros no URL fornecido, o Console de APIs sabe que deve ativar automaticamente a API Google Maps Android
  3. Crie uma chave de API e clique em Restringir chave para restringir o uso da chave a apps Android. A chave de API gerada precisa começar com AIza.
  4. No arquivo google_maps_api.xml, cole a chave na string google_maps_key em que diz YOUR_KEY_HERE.
  5. Execute o app. Você tem um mapa incorporado à sua atividade, com um marcador definido em Sydney, Austrália. O marcador de Sydney faz parte do modelo e você pode alterá-lo depois.

4. Tarefa 2: Adicionar marcadores e tipos de mapa

O Google Maps inclui vários tipos de mapa: normal, híbrido, satélite, terreno e "nenhum". Nesta tarefa, você vai adicionar uma barra de apps com um menu de opções que permite ao usuário mudar o tipo de mapa. Você move o local de partida do mapa para sua própria casa. Em seguida, você adiciona suporte para marcadores, que indicam locais únicos em um mapa e podem incluir um rótulo.

2.1 Adicionar tipos de mapa

O tipo de mapa que seu usuário quer depende do tipo de informação de que ele precisa. Ao usar mapas para navegação no seu carro, é útil ver os nomes das ruas claramente. Ao caminhar, você provavelmente se preocupa mais com o quanto precisa escalar para chegar ao topo da montanha. 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. Escolha Menu como o tipo de recurso. Clique em OK.
  3. Substitua o código no novo arquivo pelo seguinte para criar as opções de mapa. O argumento "nenhum" tipo de mapa é omitido, porque "nenhum" resulta na ausência de qualquer mapa.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item android:id="@+id/normal_map"
       android:title="@string/normal_map"
       app:showAsAction="never"/>
   <item android:id="@+id/hybrid_map"
       android:title="@string/hybrid_map"
       app:showAsAction="never"/>
   <item android:id="@+id/satellite_map"
       android:title="@string/satellite_map"
       app:showAsAction="never"/>
   <item android:id="@+id/terrain_map"
       android:title="@string/terrain_map"
       app:showAsAction="never"/>
</menu>
  1. Crie recursos de string para os atributos title.
  2. No arquivo MapsActivity, mude a classe para estender a classe AppCompatActivity em vez de estender a classe FragmentActivity. O uso de AppCompatActivity mostra a barra de apps e, portanto, o menu.
  3. Em MapsActivity, substitua o método onCreateOptionsMenu() e infle o arquivo map_options:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.map_options, menu);
   return true;
}
  1. Para mudar o tipo de mapa, use o método setMapType() no objeto GoogleMap, transmitindo uma das constantes desse tipo.

Modifique o método onOptionsItemSelected(). Cole o seguinte código para alterar o tipo de mapa quando o usuário selecionar uma das opções de menu:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
       // Change the map type based on the user's selection.
       switch (item.getItemId()) {
           case R.id.normal_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
               return true;
           case R.id.hybrid_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
               return true;
           case R.id.satellite_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
               return true;
           case R.id.terrain_map:
               mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
               return true;
           default:
               return super.onOptionsItemSelected(item);
       }
    }
  1. Execute o app. Use o menu na barra de apps para alterar o tipo de mapa. Observe como a aparência do mapa muda.

2.2 Mover o local padrão do mapa

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 etapa, você faz o mapa se movimentar até o local da sua casa sem colocar um marcador e, em seguida, aplica zoom no nível especificado.

  1. No método onMapReady(), remova o código que coloca o marcador em Sydney e move a câmera.
  2. Acesse www.google.com/maps no navegador e encontre sua casa.
  3. Clique com o botão direito do mouse no local e selecione O que há aqui?

Próximo à parte de baixo da tela, uma pequena janela aparece com informações de localização, incluindo latitude e longitude.

  1. Crie um novo objeto LatLng com o nome home. No objeto LatLng, use as coordenadas que você encontrou no Google Maps no navegador.
  2. Crie uma variável float com o nome zoom e a defina como o nível de zoom inicial desejado. 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. Crie um objeto CameraUpdate usando CameraUpdateFactory.newLatLngZoom(), transmitindo o objeto LatLng e a variável zoom. Mova e aplique zoom na câmera chamando moveCamera() no objeto GoogleMap, transmitindo o novo objeto CameraUpdate:
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, zoom));
  1. Execute o app. O mapa deve se movimentar até sua casa e o zoom no nível desejado.

2.3 Adicionar marcadores de mapa

O Google Maps pode identificar um local usando um marcador, que você cria usando a classe Marker. O marcador padrão usa o ícone padrão do Google Maps: Marcador do Google Maps

Você pode estender os marcadores para mostrar informações contextuais em janelas de informações.

Nesta etapa, você vai adicionar um marcador quando o usuário tocar e mantiver um local no mapa. Em seguida, adicione uma InfoWindow que mostre as coordenadas do marcador quando ele receber um toque.

Uma janela de informações para um alfinete inserido

  1. Crie um stub de método em MapsActivity com o nome setMapLongClick(), que usa um final GoogleMap como argumento e retorna void:
private void setMapLongClick(final GoogleMap map) {}
  1. Use o método setOnMapLongClickListener() do objeto GoogleMap para colocar um marcador onde o usuário toca e mantém pressionado. Transmita uma nova instância de OnMapLongClickListener que substitua o método onMapLongClick(). O argumento recebido é um objeto LatLng que contém as coordenadas do local que o usuário pressionou:
private void setMapLongClick(final GoogleMap map) {
   map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
       @Override
       public void onMapLongClick(LatLng latLng) {
       }
   });
}
  1. No onMapLongClick(), chame o método addMarker(). Transmita um novo objeto MarkerOptions com a posição definida como o LatLng transmitido:
map.addMarker(new MarkerOptions().position(latLng));
  1. Chame setMapLongClick() no final do método onMapReady(). Transmita mMap.
  2. Execute o app. Toque e segure no mapa para colocar um marcador em um local.
  3. Toque no marcador, que o centraliza na tela.

Os botões de navegação aparecem no canto inferior esquerdo da tela, permitindo que o usuário use o app Google Maps para navegar até a posição marcada.

Para adicionar uma janela de informações ao marcador:

  1. No objeto MarkerOptions, defina os campos title e snippet.
  2. Em onMapLongClick(), defina o campo title como "Alfinete inserido". Defina o campo snippet como as coordenadas de local dentro do método addMarker().
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
   @Override
   public void onMapLongClick(LatLng latLng) {
       String snippet = String.format(Locale.getDefault(),
               "Lat: %1$.5f, Long: %2$.5f",
               latLng.latitude,
               latLng.longitude);

       map.addMarker(new MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet));
   }
});
  1. Execute o app. Toque e segure no mapa para inserir um marcador de local. Toque no marcador para mostrar a janela de informações.

2.4 Adicionar 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. Este listener de cliques coloca um marcador no mapa imediatamente, em vez de esperar um toque segurar. O listener de cliques também exibe a janela de informações com o nome do PDI.

Marcador de ponto de interesse

  1. Crie um stub de método em MapsActivity com o nome setPoiClick(), que usa um final GoogleMap como argumento e retorna void:
private void setPoiClick(final GoogleMap map) {}
  1. No método setPoiClick(), defina um OnPoiClickListener no GoogleMap transmitido:
map.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
   @Override
   public void onPoiClick(PointOfInterest poi) {
   }
});
  1. No método onPoiClick(), coloque um marcador no local do PDI. Defina o título como o nome do PDI. Salve o resultado em uma variável com o nome poiMarker.
public void onPoiClick(PointOfInterest poi) {
   Marker poiMarker = mMap.addMarker(new MarkerOptions()
       .position(poi.latLng)
       .title(poi.name);
}
  1. Chame showInfoWindow() em poiMarker para mostrar a janela de informações imediatamente.
poiMarker.showInfoWindow();
  1. Chame setPoiClick() no final de onMapReady(). Transmita mMap.
  2. Execute o app e encontre um PDI, como um parque. Toque no PDI para inserir um marcador e exibir o nome dele em uma janela de informações.

5. Tarefa 3: 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. Use o assistente de estilo on-line para adicionar um estilo ao seu mapa e personalizar seus marcadores. Você também pode adicionar um GroundOverlay ao local da sua casa, que é dimensionado e girado com o mapa.

3.1 Adicionar um estilo ao mapa

Para criar um estilo personalizado para seu mapa, gere um arquivo JSON que especifique como os elementos do mapa serão exibidos.Você não precisa criar esse arquivo JSON manualmente: o Google fornece o assistente de estilo, que gera o JSON para você depois que você estiliza o mapa visualmente. Neste exercício, você estiliza o mapa para o "modo noturno", o que significa que o mapa usa cores escuras e baixo contraste para uso à noite.

  1. Acesse https://mapstyle.withgoogle.com/ no seu navegador.
  2. Selecione Criar um estilo.
  3. Selecione o tema Noite.
  4. Clique em Mais opções na parte de baixo do menu.
  5. Na parte de baixo da lista Tipo de elemento, selecione Água > Preenchimento. Mude a cor da água para azul-escuro (por exemplo, #160064).
  6. Clique em Finish. Copie o código JSON da janela pop-up exibida.
  7. No Android Studio, crie um diretório de recursos com o nome raw no diretório res. Crie um arquivo em res/raw com o nome map_style.json.
  8. Cole o código JSON no novo arquivo de recursos.
  9. Para definir o estilo JSON no mapa, chame setMapStyle() no objeto GoogleMap. Transmita um objeto MapStyleOptions, que carrega o arquivo JSON. O método setMapStyle() retorna um booleano indicando o sucesso do estilo. Se não for possível carregar o arquivo, o método vai gerar uma Resources.NotFoundException.

Copie o código a seguir no método onMapReady() para estilizar o mapa. Talvez seja necessário criar uma string TAG para os log statements:

     try {
        // Customize the styling of the base map using a JSON object defined
        // in a raw resource file.
        boolean success = googleMap.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
                   this, R.raw.map_style));

        if (!success) {
            Log.e(TAG, "Style parsing failed.");
        }
     } catch (Resources.NotFoundException e) {
        Log.e(TAG, "Can't find style. Error: ", e);
     }
  1. Execute o app. O novo estilo precisa ficar visível quando o mapa estiver no modo normal.

Estilo do Google Maps no modo noturno

3.2 Estilizar seu marcador

Para personalizar ainda mais seu mapa, estilize os marcadores dele. Nesta etapa, você vai mudar os marcadores vermelhos padrão para combinar com o esquema de cores do modo noturno.

  1. No método onMapLongClick(), adicione a linha de código abaixo ao construtor MarkerOptions() para usar o marcador padrão, mas mude a cor para azul:
.icon(BitmapDescriptorFactory.defaultMarker
       (BitmapDescriptorFactory.HUE_BLUE))
  1. Execute o app. Os marcadores colocados agora têm sombreamento em azul, o que é mais consistente com o tema do modo noturno do aplicativo.

Os marcadores de PDIs ainda estão vermelhos porque você não adicionou estilo ao método onPoiClick().

3.3 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. Há três tipos de sobreposições compatíveis:

  • Formas: você pode adicionar polilinhas, polígonos e círculos ao mapa.
  • Objetos TileOverlay: uma sobreposição de blocos define um conjunto de imagens adicionadas sobre os blocos do mapa básico. As sobreposições de blocos são úteis para adicionar várias imagens ao mapa. Uma sobreposição de blocos típica cobre uma grande área geográfica.
  • 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. As sobreposições de solo são úteis quando você quer corrigir uma única imagem em uma área do mapa.

Nesta etapa, você adiciona uma sobreposição de solo no formato de um dispositivo Android ao local da sua casa.

  1. Faça o download desta imagem do Android e salve na pasta res/drawable.
  2. No onMapReady(), após a chamada para mover a câmera para a posição padrão, crie um objeto GroundOverlayOptions. Atribua o objeto a uma variável com o nome homeOverlay:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions();
  1. Use o método BitmapDescriptorFactory.fromResource() para criar um objeto BitmapDescriptor da imagem acima. Transmita o objeto para o método image() do GroundOverlayOptions:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
    .image(BitmapDescriptorFactory.fromResource(R.drawable.android));
  1. Defina a propriedade position para o objeto GroundOverlayOptions chamando o método position(). Transmita o objeto home LatLng e um float para a largura em metros da sobreposição desejada. Para este exemplo, uma largura de 100 m funciona bem:
GroundOverlayOptions homeOverlay = new GroundOverlayOptions()
     .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
       .position(home, 100);
  1. Chame addGroundOverlay() no objeto GoogleMap. Transmita o objeto GroundOverlayOptions:
mMap.addGroundOverlay(homeOverlay);
  1. Execute o app. Aumente o zoom no local da sua casa. Você verá a imagem do Android como uma sobreposição.

6. Tarefa 4: Ativar o rastreamento de localização e o Street View

Geralmente, os usuários usam o Google Maps para saber a localização atual deles, e você pode consultar a localização do dispositivo usando a API Location Services. Para mostrar o local do dispositivo no mapa sem usar mais os dados do Location, use a camada de dados de local.

A camada de dados de localização adiciona um botão Meu local à parte superior direita do mapa. Quando o usuário toca no botão, o mapa centraliza a localização do dispositivo. A localização será exibida como um ponto azul se o dispositivo estiver parado e como uma seta azul se ele estiver em movimento.

Um mapa do Google com rastreamento de local

Você pode fornecer informações adicionais sobre um local usando o Google Street View, que é uma foto panorâmica navegável de um determinado local.

Nesta tarefa, você vai ativar a camada de dados de local e o Street View para que o mapa entre no modo Street View quando o usuário tocar na janela de informações do marcador de PDI.

4.1 Ativar o rastreamento 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.
  2. Para ativar o acompanhamento de local no seu app, crie um método na MapsActivity com o nome enableMyLocation(), que não recebe argumentos e não retorna nada.
  3. Defina o método enableMyLocation(). 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 void enableMyLocation() {
   if (ContextCompat.checkSelfPermission(this,
           Manifest.permission.ACCESS_FINE_LOCATION)
           == PackageManager.PERMISSION_GRANTED) {
       mMap.setMyLocationEnabled(true);
   } else {
       ActivityCompat.requestPermissions(this, new String[]
                       {Manifest.permission.ACCESS_FINE_LOCATION},
               REQUEST_LOCATION_PERMISSION);
   }
}
  1. Chame enableMyLocation() do callback onMapReady() para ativar a camada de localização.
  2. Modifique o método onRequestPermissionsResult(). Se a permissão tiver sido concedida, chame enableMyLocation():
@Override
public void onRequestPermissionsResult(int requestCode,
       @NonNull String[] permissions,
       @NonNull int[] grantResults) {
   // Check if location permissions are granted and if so enable the
   // location data layer.
   switch (requestCode) {
       case REQUEST_LOCATION_PERMISSION:
           if (grantResults.length > 0
                   && grantResults[0]
                   == PackageManager.PERMISSION_GRANTED) {
               enableMyLocation();
               break;
           }
   }
}
  1. Execute o app. O canto superior direito agora contém o botão Meu local, que exibe a localização atual do dispositivo.

4.2 Ativar o Street View

O Google Maps oferece o Street View, que é uma visualização panorâmica de um local com controles para navegar por um caminho designado. O Street View não tem cobertura global.

Nesta etapa, você vai ativar um panorama do Street View que é ativado quando o usuário toca na janela de informações de um PDI. Você precisa fazer duas coisas:

  1. Diferencie os marcadores de PDIs de outros porque você quer que a funcionalidade do seu app funcione somente nesses marcadores. Dessa forma, você pode iniciar o Street View quando o usuário toca em uma janela de informações de PDI, mas não em qualquer outro tipo de marcador.

A classe Marker inclui um método setTag() que permite anexar dados. Os dados podem ser qualquer coisa que se estenda do Object. Defina uma tag nos marcadores criados quando os usuários clicam em PDIs.

  1. Quando o usuário toca em uma janela de informações com tag em uma OnInfoWindowClickListener, substitua MapFragment por um StreetViewPanoramaFragment. O código abaixo usa SupportMapFragment e SupportStreetViewPanoramaFragment para oferecer suporte a versões do Android anteriores ao nível 12.

Se algum dos fragmentos mudar durante a execução, será necessário adicioná-los à classe Activity que os contém, e não estaticamente em XML.

Marcar o marcador de PDI

  1. No callback onPoiClick(), chame setTag() em poiMarker. Transmita qualquer string arbitrária:
poiMarker.setTag("poi");

Substituir o SupportMapFragment estático por uma instância de ambiente de execução

  1. Abra activity_maps.xml e mude o elemento para um layout de frame que servirá como o contêiner dos seus fragmentos:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/fragment_container"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />
  1. Em onCreate() no MapsActivity, remova o código que encontra o SupportMapFragment pelo ID, porque não há mais um SupportMapFragment estático no XML. Em vez disso, crie uma nova instância de ambiente de execução do SupportMapFragment chamando SupportMapFragment.newInstance():
SupportMapFragment mapFragment = SupportMapFragment.newInstance();
  1. Adicione o fragmento ao FrameLayout usando uma transação de fragmento com o FragmentManager:
getSupportFragmentManager().beginTransaction()
       .add(R.id.fragment_container, mapFragment).commit();
  1. Mantenha a linha de código que aciona o carregamento assíncrono do mapa:
mapFragment.getMapAsync(this);

Definir um OnjanelaClickListener e verificar a tag do marcador

  1. Crie um stub de método em MapsActivity com o nome setInfoWindowClickToPanorama(), que usa um GoogleMap como argumento e retorna void:
private void setInfoWindowClickToPanorama(GoogleMap map) {}
  1. Defina um OnInfoWindowClickListener para o GoogleMap:
map.setOnInfoWindowClickListener(
       new GoogleMap.OnInfoWindowClickListener() {
           @Override
           public void onInfoWindowClick(Marker marker) {
           }
       });
  1. No método onInfoWindowClick(), verifique se o marcador contém a tag de string que você definiu no método onPoiClick():
if (marker.getTag() == "poi") {}

Substituir o SupportMapFragment por um SupportStreetViewPanoramaFragment

  1. Quando o marcador tiver a tag, especifique o local do panorama do Street View usando um objeto StreetViewPanoramaOptions. Defina a propriedade position do objeto de acordo com a posição do marcador transmitido:
StreetViewPanoramaOptions options =
       new StreetViewPanoramaOptions().position(
               marker.getPosition());
  1. Crie uma nova instância de SupportStreetViewPanoramaFragment, transmitindo o objeto options criado:
SupportStreetViewPanoramaFragment streetViewFragment
       = SupportStreetViewPanoramaFragment
       .newInstance(options);
  1. Inicie uma transação de fragmento. Substitua o conteúdo do contêiner do fragmento pelo novo fragmento, streetViewFragment. Adicione a transação à backstack para que, ao pressionar "Voltar", você volte ao SupportMapFragment e não saia do app:
getSupportFragmentManager().beginTransaction()
       .replace(R.id.fragment_container,
               streetViewFragment)
       .addToBackStack(null).commit();
  1. Chame setInfoWindowClickToPanorama(mMap) em onMapReady() após a chamada para setPoiClick().
  2. Execute o app. Aumente o zoom em uma cidade que tenha cobertura do Street View, como Mountain View (casa da sede do Google), e encontre um PDI, como um parque. Toque no PDI para inserir um marcador e mostrar a janela de informações. Toque na janela de informações para entrar no modo Vista da rua para o local do marcador. Pressione o botão "Voltar" para retornar ao fragmento de mapa.

Google Street View em um app Android

7. Código da solução

Código da solução do Wander.

8. Desafio de programação

Desafio:se você tocar na janela de informações de um PDI em um local onde não há cobertura do Street View, uma tela preta será exibida.

9. Resumo

  • 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 uma 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 durante a execução, use o método GoogleMap.setMapType(). Um mapa do Google pode ser de um dos seguintes tipos:

  • Normal: mapa de vias típico. Mostra estradas, alguns elementos construídos 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 adicionados. 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.
  • Terreno: 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**:** sem mapa.

Sobre o Google Maps:

  • Um marcador é um indicador de uma localização geográfica específica.
  • Quando tocado, o comportamento padrão do marcador é exibir uma janela de informações 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. Os PDIs incluem parques, escolas, edifícios governamentais e muito mais.
  • Além disso, os PDIs de empresas (lojas, restaurantes, hotéis e muito mais) aparecem por padrão no mapa quando o tipo dele é normal.
  • Você pode capturar cliques em PDIs usando OnPoiClickListener.
  • É possível alterar a aparência 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 ao Google Maps usando o método setMapStyle().
  • Você pode personalizar seus marcadores alterando a cor padrão ou substituindo o ícone de 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 em metros e a posição dela. Transmita esse objeto ao método GoogleMap.addGroundOverlay() para definir a sobreposição do mapa.
  • Se o app tiver a permissão ACCESS_FINE_LOCATION, você poderá ativar o rastreamento de localização usando o método mMap.setMyLocationEnabled(true).
  • O Street View do Google proporciona visualizações panorâmicas de 360 graus de vias designadas em toda sua área de cobertura.
  • Use o método StreetViewPanoramaFragment.newInstance() para criar um novo fragmento do Street View.
  • Para especificar as opções da visualização, use um objeto StreetViewPanoramaOptions. Transmita o objeto para o método newInstance().

10. Saiba mais

A documentação do conceito relacionado está na 9.1: API Google Maps.

Documentação do desenvolvedor Android:

Documentação de referência:

11. Dever de casa

Esta seção lista as possíveis atividades de dever de casa para os alunos que estão fazendo este codelab como parte de um curso ministrado por um professor. Cabe ao professor fazer o seguinte:

  • Atribuir o dever de casa, se necessário.
  • Informar aos alunos como enviar deveres de casa.
  • Atribuir nota aos deveres de casa.

Os professores podem usar essas sugestões o quanto quiserem, podendo passar os exercícios que acharem mais apropriados como dever de casa.

Se você estiver seguindo este codelab por conta própria, sinta-se à vontade para usar esses deveres de casa para testar seu conhecimento.

Criar e executar um app

  1. Crie um novo app que use o modelo de atividades no Google Maps, que carrega o Google Maps quando o app é iniciado.
  2. Quando o mapa do Google for carregado, mova a câmera para o local da sua escola, sua casa ou algum outro local que seja importante para você.
  3. Adicione dois marcadores ao mapa: um na sua escola e outro em sua casa ou outro local significativo.
  4. Personalize os ícones de marcadores alterando a cor padrão ou substituindo o ícone de marcador padrão por uma imagem personalizada.

Dica:consulte a documentação do onMapReady (GoogleMap googleMap).

Responda estas perguntas

Pergunta 1

Qual método é chamado quando o mapa é carregado e está pronto para ser usado no app?

Pergunta 2

Quais componentes do Android você pode usar para incluir o Google Maps no seu app?

  • MapView e MapFragment
  • MapFragment e MapActivity
  • MapView e MapActivity
  • Somente MapFragment

Pergunta 3

Que tipos de mapas a API do Google Maps para Android oferece?

  • Normal, híbrido, terreno, satélite e roteiro
  • Normal, híbrido, terreno, satélite e "nenhum"
  • Híbrido, terreno, satélite, mapa e "nenhum"
  • Normal, terreno, satélite, mapa de imagens e "nenhum"

Pergunta 4

Qual interface você implementa para adicionar a funcionalidade de clique a um ponto de interesse (PDI)?

  • GoogleMap.OnPoiListener
  • GoogleMap.OnPoiClickListener
  • GoogleMap.OnPoiClick
  • GoogleMap.OnPoiClicked

Enviar o app para avaliação

Orientação para os avaliadores

Verifique se o app tem estes recursos:

  • Quando o app é iniciado, o mapa do Google é exibido corretamente, indicando que uma chave de API foi gerada corretamente.
  • Depois que o mapa é carregado, a câmera se move para a casa ou escola do estudante. No código, essa etapa precisa acontecer no método de callback onMapReady (GoogleMap googleMap).
  • Os marcadores são exibidos na escola do aluno e em outro local, como a casa dele.
  • Os dois marcadores são personalizados. Por exemplo, os marcadores usam uma cor diferente da cor vermelha padrão ou usam um ícone personalizado.

12. Próximo codelab

Para conferir todos os codelabs do curso de treinamento Desenvolvimento avançado para Android, acesse a página de destino dos codelabs de Desenvolvimento avançado para Android.