Criar um app de navegação simples para Android com o SDK Navigation da Plataforma Google Maps
Sobre este codelab
1. Antes de começar
Este codelab ensina a criar um app Android simples que usa o SDK de navegação da Plataforma Google Maps para navegar até um destino pré-configurado.
O app vai ficar assim quando você terminar.
Pré-requisitos
- Conhecimento básico de desenvolvimento de apps Android em Kotlin
- Familiaridade com conceitos básicos do SDK do Google Maps, como mapas, locais e coordenadas.
O que você vai aprender
- Como criar um app Android simples que usa o SDK do Navigation para navegar até um destino.
- Como integrar o SDK Navigation do repositório remoto do Maven do Google
- Como gerenciar permissões de localização e o contrato do usuário com os Termos do usuário final do SDK de navegação
- Como inicializar o SDK
- Como definir um destino e iniciar as orientações de navegação.
O que é necessário
- A versão estável mais recente do Android Studio instalada. Este codelab foi criado usando o Android Studio Jellyfish. Se você usa uma versão diferente, a aparência e o layout da interface e dos componentes podem variar.
- Uma Conta do Google e um projeto com faturamento ativado.
- Um dispositivo Android no modo de desenvolvedor com a depuração USB ativada ou um emulador do Android. A opção escolhida precisa atender aos requisitos mínimos do SDK do Navigation.
2. Começar a configuração
Se você ainda não tiver uma conta do Google Cloud Platform e um projeto com faturamento ativado, configure seu projeto do Google Cloud seguindo as instruções de primeiros passos da Plataforma Google Maps https://developers.google.com/maps/gmp-get-started
Selecione seu projeto do Google Cloud no console.
No Console do Cloud, clique no menu suspenso do projeto e selecione a opção que você quer usar neste codelab.
Ativar o SDK do Navigation no seu projeto
Ative as APIs e os SDKs da Plataforma Google Maps necessários para este codelab no Google Cloud Marketplace.
Acesse as APIs e Serviços > no console do Google Cloud e pesquise "SDK do Navigation".
Você vai encontrar um resultado da pesquisa.
Clique no resultado do SDK do Navigation para abrir a página "Detalhes do produto". Clique no botão "Ativar" para ativar o SDK no seu projeto.
Repita esse processo com o SDK do Google Maps para Android.
crie uma chave de API
Gere uma chave de API na página Credenciais do Console do Cloud. Siga as etapas na etapa 3 da seção de início rápido em Começar a usar a Plataforma Google Maps. Todas as solicitações à Plataforma Google Maps exigem uma chave de API.
3. Conseguir os arquivos de exemplo do projeto
Esta seção descreve como configurar um projeto básico e vazio do Android Studio clonando arquivos do repositório do GitHub para este codelab. O repositório do GitHub contém versões anteriores e posteriores do código do codelab. O codelab vai começar com um modelo de projeto vazio e evoluir até o estado final. Se você ficar preso, use o projeto concluído no repositório como referência.
Clone este repositório do GitHub para acessar o código deste codelab.
git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git
Se você não tiver o git instalado, clique neste botão para receber o código:
Para começar o mais rápido possível, o repositório contém um código inicial na pasta Starter
para ajudar você a acompanhar este codelab. O projeto inicial fornece uma interface básica do app e uma configuração de build, mas não tem o SDK Navigation adicionado. Há também um projeto Solution
concluído, caso você queira avançar ou verificar seu progresso a qualquer momento.
Abrir o repositório clonado no Android Studio
Depois de clonar o repositório localmente, use o Android Studio para abrir a pasta Starter
como um projeto.
- Na caixa de diálogo "Welcome to Android Studio", clique no botão "Open".
- Navegue até a pasta em que você salvou o repositório clonado e selecione a pasta
Starter
dentro do nível superior "codelab-navigation-101-android-kotlin
" do Compute Engine. - Verifique se o projeto é criado e executado.
Adicionar um dispositivo virtual ou conectar um dispositivo de hardware
Para conectar um dispositivo Android ao computador, siga as instruções do Android Studio sobre como Executar apps em um dispositivo de hardware. Também é possível configurar um dispositivo virtual usando o Gerenciador de dispositivos virtuais Android (AVD). Ao escolher um emulador, selecione uma imagem que inclua as APIs do Google.
No Android Studio, clique na opção de menu "Run" ou no ícone do botão de reprodução. Escolha um dispositivo quando solicitado.
4. Adicionar o SDK do Navigation ao seu app
Adicionar a biblioteca do SDK do Navigation e sua chave de API ao projeto
Para adicionar a biblioteca do SDK de navegação ao seu app, é necessário modificar o build.gradle.kts
do nível do app para buscar o SDK de navegação do repositório Maven do Google e configurar um número de versão.
Crie uma variável na configuração do build para armazenar o número da versão do SDK do Navigation.
Configure uma variável no build.gradle.kts
no nível do app para conter o valor da versão do SDK de navegação usada no app, de modo que seja fácil mudar para a versão mais recente no futuro.
Consulte as notas da versão do SDK do Navigation para saber o número da versão mais recente.
val navSdkVersion by extra("6.0.0")
Também é possível modificar os valores dessa e de outras variáveis usando a caixa de diálogo em Arquivo > Estrutura do projeto > Variáveis:
Adicionar uma dependência à configuração do build
Agora, adicione a seguinte dependência de API ao bloco de dependências no nível do app. build.gradle.kts.
A versão usada será o valor de ${navSdkVersion}
que você acabou de definir no build.gradle.kts
:
dependencies {
// Include the Google Navigation SDK.
api("com.google.android.libraries.navigation:navigation:${navSdkVersion}")
...
Adicionar sua chave de API
Usar o plug-in Secrets Gradle para gerenciar a chave de API
Recomendamos o uso do plug-in Secrets Gradle para gerenciar com segurança a chave de API no app. O plug-in foi adicionado ao modelo de projeto inicial como uma dependência no arquivo build.gradle.kts
de nível superior.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") version "2.0.1" apply false
//... other plugin definitions here
}
Abra o arquivo secrets.properties
no diretório de nível superior e substitua YOUR_API_KEY
pela sua chave de API. Armazene sua chave nesse arquivo porque secrets.properties
não é verificado em um sistema de controle de versões.
MAPS_API_KEY=YOUR_API_KEY
Para mais informações sobre esse assunto, consulte Adicionar a chave de API ao app na documentação do SDK de navegação.
Verificar o conteúdo de local.defaults.properties
O projeto vazio também contém um arquivo local.defaults.properties
no seu diretório de nível superior, a mesma pasta que o arquivo secrets.properties
. Abra-o e observe o código a seguir.
MAPS_API_KEY=DEFAULT_API_KEY
Ele existe para fornecer um valor de backup para a propriedade MAPS_API_KEY
caso secrets.properties
não seja adicionado ao projeto, para que os builds não falhem. Não é necessário editar este arquivo. Se a definição secrets.properties
de MAPS_API_KEY
não for encontrada, o valor padrão vai interromper a execução do app no momento da execução, com um erro de chave de API.
Verificar se o manifesto do Android está usando a chave de API especificada
Abra app/src/main/AndroidManifest.xml. A propriedade MAPS_API_KEY
é usada para definir a chave de API do aplicativo:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
Abra o arquivo build.gradle.kts
do app e encontre a propriedade secrets
.
A configuração propertiesFileName
do plug-in precisa ser definida como secrets.properties
, e defaultPropertiesFileName
precisa ser local.defaults.properties
.
secrets {
// Optionally specify a different file name containing your secrets.
// The plugin defaults to "local.properties"
propertiesFileName = "secrets.properties"
// A properties file containing default secret values. This file can be
// checked in version control.
defaultPropertiesFileName = "local.defaults.properties"
}
Salve todos os arquivos e sincronize seu projeto com o Gradle.
5. Configurar as permissões do app e adicionar uma interface básica
Solicitar permissão de local exato
O SDK de navegação depende de sinais de GPS para funcionar. Portanto, seu app precisa pedir ao usuário para conceder acesso a dados de localização precisos. Adicione a permissão para acessar a localização precisa como um elemento filho de <manifest>
no AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
</manifest>
Saiba mais sobre as permissões de localização do Android na seção Solicitar permissões de localização da documentação do desenvolvedor Android.
Para executar o app em um dispositivo Android 14, solicite a permissão de localização de serviço em primeiro plano adicionando a seguinte tag uses-permission
no mesmo local da permissão de acesso à localização exata:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
Adicionar uma atividade de inicialização com uma interface básica
Quando o app for executado, ele precisará do código que é executado durante a inicialização para verificar se o usuário concedeu permissão para acessar a localização e processar cada cenário possível, solicitando a permissão se ela ainda não tiver sido concedida. Para fazer isso, adicione uma interface do usuário básica ao app. Este codelab usa a interface que é criada quando você cria uma nova atividade de visualizações vazia no Android Studio. Você vai adaptar isso para realizar a verificação de permissão de localização antes de adicionar código à atividade para a interface de navegação.
Abra o arquivo MainActivity.kt
no editor de código e inspecione o código, que mostra uma interface básica.
Solicitar permissões de acesso à localização no momento da execução
O app precisa acionar a solicitação para acessar a localização exata antes que o SDK de navegação seja inicializado.
Para garantir que essa verificação aconteça quando o app for iniciado, adicione um código à classe MainActivity
no método onCreate()
substituído da atividade.
O código a seguir verifica se o usuário concedeu a permissão de localização exata. Em caso negativo, a permissão é solicitada. Adicione este código ao método onCreate()
.
val permissions =
if (VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
arrayOf(permission.ACCESS_FINE_LOCATION, permission.POST_NOTIFICATIONS)
} else {
arrayOf(permission.ACCESS_FINE_LOCATION)
}
if (permissions.any { !checkPermissionGranted(it) }) {
if (permissions.any { shouldShowRequestPermissionRationale(it) }) {
// Display a dialogue explaining the required permissions.
}
val permissionsLauncher =
registerForActivityResult(
RequestMultiplePermissions(),
{ permissionResults ->
if (permissionResults.getOrDefault(permission.ACCESS_FINE_LOCATION, false)) {
onLocationPermissionGranted()
} else {
finish()
}
},
)
permissionsLauncher.launch(permissions)
} else {
android.os.Handler(Looper.getMainLooper()).postDelayed({ onLocationPermissionGranted() }, SPLASH_SCREEN_DELAY_MILLIS)
}
}
private fun checkPermissionGranted(permissionToCheck: String): Boolean =
ContextCompat.checkSelfPermission(this, permissionToCheck) == PackageManager.PERMISSION_GRANTED
Adicione uma nova função à classe MainActivity
, chamada onLocationPermissionGranted
, que processará o resultado quando o usuário conceder permissão para compartilhar a localização. Nas próximas etapas, vamos adicionar um código aqui para iniciar uma nova atividade de navegação.
private fun onLocationPermissionGranted() {
//code to initialize Navigation SDK will go here
}
Crie o projeto. Se houver erros de build, encontre e corrija-os.
Execute o projeto em um novo dispositivo virtual. A caixa de diálogo de solicitação de permissão vai aparecer quando o app for instalado e iniciado.
6. Adicionar uma interface do usuário de navegação
Há duas maneiras de adicionar uma interface de navegação: SupportNavigationFragment
ou NavigationView
.
Para simplificar, o codelab usa um NavigationView
.
Editar o layout
Edite o res/layout/activity_main.xml
para adicionar um layout a uma NavigationView.
- Abra o arquivo e mude para a Visualização de código.
- Substitua todo o conteúdo do arquivo por um novo layout de um
NavigationView
dentro de umRelativeLayout
, como no exemplo abaixo. Como você vai adicionar apenas uma visualização de navegação ao app, um layout simples basta. - Defina o ID
@+id/navigation_view
para a NavigationView.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.libraries.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Configurar a atividade de navegação
No Android Studio, abra o arquivo MainActivity.kt no editor.
Adicione um código de configuração básico para garantir que a experiência de navegação funcione corretamente no app. No arquivo MainActivity.kt, faça as seguintes mudanças:
- Declare uma variável na classe
MainActivity
para fazer referência àNavigationView
:
private lateinit var navView: NavigationView
- Adicione um código ao método
onCreate()
para acessar uma referência ao seuNavigationView
:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
- Adicione código ao método
onCreate()
para garantir que a tela permaneça ativada durante a orientação de navegação:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- Edite o código que chama
ViewCompat.setOnApplyWindowInsetsListener
para referenciar o ID doNavigationView
.
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.navigation_view)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
- Adicione um método
showToast()
à classe para mostrar feedback ao usuário:
private fun showToast(errorMessage: String) {
Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG).show()
}
7. Inicializar o SDK do Navigation
Agora que você concluiu a configuração básica da atividade de navegação, é possível inicializar o SDK de navegação. Para fazer isso, adicione o seguinte código ao seu arquivo MainActivity.kt:
/** Starts the Navigation API, capturing a reference when ready. */
@SuppressLint("MissingPermission")
private fun initializeNavigationApi() {
NavigationApi.getNavigator(
this,
object : NavigatorListener {
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
// code to start guidance will go here
}
override fun onError(@NavigationApi.ErrorCode errorCode: Int) {
when (errorCode) {
NavigationApi.ErrorCode.NOT_AUTHORIZED -> {
// Note: If this message is displayed, you may need to check that
// your API_KEY is specified correctly in AndroidManifest.xml
// and is been enabled to access the Navigation API
showToast(
"Error loading Navigation API: Your API key is " +
"invalid or not authorized to use Navigation."
)
}
NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> {
showToast(
"Error loading Navigation API: User did not " +
"accept the Navigation Terms of Use."
)
}
else -> showToast("Error loading Navigation API: $errorCode")
}
}
},
)
}
Esse código cria um novo método chamado initializeNavigationApi()
. Esse método recebe uma referência a um objeto Navigator
chamando NavigationApi.getNavigator()
e implementa um NavigatorListener
para processar o callback.
Quando a API Navigation for inicializada, o método NavigationListener.onNavigatorReady
será invocado, com um objeto Navigator
transmitido como um parâmetro. O código acima vai atualizar a variável mNavigator
declarada anteriormente com o objeto Navigator
inicializado que é transmitido a esse método.
Por fim, adicione uma chamada ao método initializeNavigationApi
usando o método onLocationPermissionGranted
.
private fun onLocationPermissionGranted() {
initializeNavigationApi()
}
8. Adicionar listeners para eventos de navegação principais
Quando os usuários estão seguindo as orientações, o SDK do Navigation aciona eventos que notificam o app sobre mudanças importantes de estado no trajeto, como quando o usuário redireciona ou chega ao destino. No arquivo MainActivity.kt, adicione listeners para processar estes eventos:
- Na classe
MainActivity
, declare duas variáveis para se referir a objetos de listener de eventos:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
- Adicione um método
registerNavigationListeners()
para configurar os listeners quando o Navigator for inicializado. Esse método chamaNavigator.clearDestinations()
para redefinir oNavigationView
quando o evento de chegada é acionado:
/**
* Registers a number of example event listeners that show an on screen message when certain
* navigation events occur (e.g. the driver's route changes or the destination is reached).
*/
private fun registerNavigationListeners() {
withNavigatorAsync {
arrivalListener =
Navigator.ArrivalListener { // Show an onscreen message
showToast("User has arrived at the destination!")
mNavigator?.clearDestinations()
}
mNavigator?.addArrivalListener(arrivalListener)
routeChangedListener =
Navigator.RouteChangedListener { // Show an onscreen message when the route changes
showToast("onRouteChanged: the driver's route changed")
}
mNavigator?.addRouteChangedListener(routeChangedListener)
}
}
- Adicione uma chamada para
registerNavigationListeners()
do código de callbackonNavigatorReady
no métodoinitializeNavigationApi
:
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
//listen for events en route
registerNavigationListeners()
}
- Configurar a interface do usuário. É possível controlar vários aspectos da interface do usuário de navegação quando a orientação está em execução. Uma personalização importante é a posição da câmera. Adicione uma chamada ao método
setTaskRemovedBehaviour
do retorno do objetonavigator
emonNavigatorReady
da seguinte maneira. Isso vai encerrar a orientação e a notificação se o app for deslizado para fora da tela:
// Disables the guidance notifications and shuts down the app and background service
// when the user dismisses/swipes away the app from Android's recent tasks.
navigator.setTaskRemovedBehavior(Navigator.TaskRemovedBehavior.QUIT_SERVICE)
- Adicione uma chamada a
GoogleMap.followMyLocation
para especificar umCameraPerspective
. OGoogleMap
é acessado pelo métodoNavigatorView.getMapAsync()
da seguinte maneira:
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
- Para garantir que a navegação funcione sem problemas durante o ciclo de vida do app, implemente os métodos abaixo na classe
MainActivity
:
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
navView.onSaveInstanceState(savedInstanceState)
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
navView.onTrimMemory(level)
}
override fun onStart() {
super.onStart()
navView.onStart()
}
override fun onResume() {
super.onResume()
navView.onResume()
}
override fun onPause() {
navView.onPause()
super.onPause()
}
override fun onConfigurationChanged(configuration: Configuration) {
super.onConfigurationChanged(configuration)
navView.onConfigurationChanged(configuration)
}
override fun onStop() {
navView.onStop()
super.onStop()
}
override fun onDestroy() {
navView.onDestroy()
withNavigatorAsync {
// Unregister event listeners to avoid memory leaks.
if (arrivalListener != null) {
navigator.removeArrivalListener(arrivalListener)
}
if (routeChangedListener != null) {
navigator.removeRouteChangedListener(routeChangedListener)
}
navigator.simulator?.unsetUserLocation()
navigator.cleanup()
}
super.onDestroy()
}
9. Definir um destino
Agora você está pronto para definir um destino e iniciar as orientações de navegação. No arquivo MainActivity.kt, faça as seguintes alterações:
- Adicione um novo método
navigateToPlace()
que define o destino de navegação e aceita um parâmetroplaceId
.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {
}
- No método
navigateToPlace()
, useWaypoint.builder()
para criar umWaypoint
usando o ID de lugar transmitido ao método. Processe oUnsupportedPlaceIdException
que pode ser gerado em situações em que o ID de lugar não é resolvido em um endereço preciso:
val waypoint: Waypoint? =
// Set a destination by using a Place ID (the recommended method)
try {
Waypoint.builder().setPlaceIdString(placeId).build()
} catch (e: Waypoint.UnsupportedPlaceIdException) {
showToast("Place ID was unsupported.")
return
}
- Adicione o seguinte código ao método
navigateToPlace()
para definir um destino usando o Waypoint:
val pendingRoute = mNavigator?.setDestination(waypoint)
// Set an action to perform when a route is determined to the destination
pendingRoute?.setOnResultListener { code ->
when (code) {
RouteStatus.OK -> {
// Code to start guidance will go here
}
RouteStatus.ROUTE_CANCELED -> showToast("Route guidance canceled.")
RouteStatus.NO_ROUTE_FOUND,
RouteStatus.NETWORK_ERROR ->
// TODO: Add logic to handle when a route could not be determined
showToast("Error starting guidance: $code")
else -> showToast("Error starting guidance: $code")
}
}
O objeto Navigator
tem um método setDestinations()
que pode receber vários parâmetros. A opção mais básica é fornecer um Waypoint
. O padrão será um modo de transporte de DRIVING
, adequado para carros de quatro rodas. O método setDestinations()
retorna um objeto ListenableResultFuture
que contém um objeto RouteStatus
. O RouteStatus
indica se uma rota foi encontrada até o destino e permite processar vários estados de erro.
- Faça outras mudanças na configuração para melhorar a experiência do usuário na navegação:
// Hide the toolbar to maximize the navigation UI
supportActionBar?.hide()
// Enable voice audio guidance (through the device speaker)
mNavigator?.setAudioGuidance(Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE)
// Simulate vehicle progress along the route (for demo/debug builds)
if (BuildConfig.DEBUG) {
mNavigator?.simulator?.simulateLocationsAlongExistingRoute(
SimulationOptions().speedMultiplier(5f)
)
}
Essas mudanças incluem as seguintes melhorias:
- Ocultar a barra de ações para maximizar o espaço da interface de navegação.
- Ativar a orientação por áudio para ouvir alertas e instruções de navegação.
- Configurar o Simulador para depuração especificando um multiplicador de velocidade.
- Encontre um ID de lugar que funcionará como destino. O ideal é que ele não fique muito longe da localização do usuário. Use o utilitário Place ID Finder da Plataforma Google Maps ou receba um ID de lugar de uma chamada da API Places.
Se você estiver simulando a navegação, poderá definir a localização do usuário no código ou tirá-la do dispositivo conectado. O codelab presume que você esteja simulando um local em Londres, Reino Unido.
- Adicione um objeto complementar à classe
MainActivity
para armazenar um local de partida e um ID de lugar. O codelab usará um local de início em Londres e o ID de lugar da Trafalgar Square:
companion object{
const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
val startLocation = LatLng(51.345678, -0.1234456)
}
- Adicione uma chamada ao método
navigateToPlace()
do callbackonNavigatorReady
dentro do métodoinitializeNavigationApi
e adicione uma ramificação de lógica que será executada no modo de depuração e define a localização do usuário:
// Disables the guidance notifications and shuts down the app and background service
// when the user dismisses/swipes away the app from Android's recent tasks.
navigator.setTaskRemovedBehavior(Navigator.TaskRemovedBehavior.QUIT_SERVICE)
mNavigator = navigator
if (BuildConfig.DEBUG) {
mNavigator?.simulator?.setUserLocation(MainActivity.startLocation)
}
//listen for events en route
registerNavigationListeners()
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
//navigate to a destination
navigateToPlace(MainActivity.TRAFALGAR_SQUARE)
10. Criar e executar o código
Na primeira vez que você executar o app, será necessário conceder permissões de localização e aceitar os Termos de Uso do SDK do Navigation.
Observação: a execução do app vai chamar o método setDestinations(), que gera uma cobrança após os primeiros 1.000 destinos usados. Consulte Uso e faturamento para mais informações.
Configurar o local
Por padrão, a localização do dispositivo emulado pode ser definida como o campus do Google em Mountain View, na Califórnia, a menos que você tenha definido essa informação no código ou usando a caixa de diálogo de propriedades do emulador.
Nesse caso, o app não consegue encontrar uma rota para o ID do lugar que você configurou (por padrão, Sydney Opera House, Sydney, Austrália). Isso é indicado por uma mensagem que diz "Nenhum trajeto encontrado", exibida pelo seu método showToast()
.
Programar o local de início
Para definir um local diferente no código, adicione a linha a seguir ao método navigateToPlace()
em MainActivity.kt, antes da chamada para mNavigator.startGuidance()
:
mNavigator?.simulator?.setUserLocation(startLocation)
Como iniciar o emulador em um local padrão de sua escolha
Para definir um local diferente no emulador de dispositivo, inicie o emulador, se ele ainda não estiver em execução, e clique no menu de três pontos com a dica "Controles estendidos". A caixa de diálogo exibida tem uma opção de menu para "Local".
Por exemplo, se você estiver usando o ID do lugar da Casa de Ópera de Sydney como destino, escolha um local em Sydney, na Austrália. Por exemplo, pesquise "Bondi beach", selecione uma sugestão e clique em "Salvar local" no canto inferior direito da caixa de diálogo. Você também pode clicar em "Salvar ponto" para adicionar o local a uma lista salva para uso futuro.
Se você definir um ID de lugar diferente como destino, escolha um local próximo para que o trajeto simulado seja realista e não muito longo para facilitar a depuração.
Reinicie o app para que ele navegue até o destino.
11. Parabéns!
Você concluiu este codelab. Muito bem! Você chegou ao seu destino. Boa codificação :-)
12. Como ir além
Se você quiser levar o desenvolvimento do seu app ainda mais, dê uma olhada nos tópicos a seguir para se inspirar.
- Detectar mais eventos de navegação. Adicione um código para mostrar uma mensagem se o motorista mudar o trajeto ou quando ele chegar.
- Personalizar a interface de navegação.
- Se você prefere um desafio maior, tente adicionar um controle Place Picker da API Places para permitir que o usuário defina o destino. Dica: os apps de demonstração do SDK do Navigation no GitHub têm um exemplo de implementação (link em inglês).
- Evite possíveis problemas ao chamar os objetos Navigator e GoogleMap de forma assíncrona adotando a abordagem usada nos apps de demonstração do SDK do Navigation no GitHub. Em cenários de app mais complexos, esses objetos podem não ter terminado de inicializar quando o código é executado. Dica: você pode adicionar a classe InitializedNavScope no final do arquivo MainActivity.kt para uma implementação muito rápida.