Crea una app de navegación simple para Android con el SDK de Navigation de Google Maps Platform
Acerca de este codelab
1. Antes de comenzar
En este codelab, aprenderás a crear una app para Android simple que use el SDK de Navigation de Google Maps Platform para navegar a un destino preconfigurado.
Así se verá tu app cuando hayas terminado.
Requisitos previos
- Conocimientos sobre desarrollo básico de apps para Android en Kotlin
- Estar familiarizados con los conceptos básicos del SDK de Google Maps, como mapas, ubicaciones y coordenadas
Qué aprenderás
- Cómo crear una app para Android simple que use el SDK de Navigation para navegar a un destino
- Cómo integrar el SDK de Navigation desde el repositorio remoto de Google Maven
- Cómo administrar los permisos de ubicación y el acuerdo del usuario con las condiciones para el usuario final del SDK de Navigation
- Cómo inicializar el SDK
- Cómo establecer un destino y comenzar la guía de navegación
Requisitos
- La versión estable más reciente de Android Studio instalada Este codelab se creó con Android Studio Jellyfish. Si usas una versión diferente, es posible que la apariencia y el diseño de la interfaz y los componentes varíen.
- Una Cuenta de Google y un proyecto con la facturación habilitada
- Un dispositivo Android en modo de desarrollador con la depuración por USB habilitada o un emulador de Android Cualquiera que elijas debe cumplir con los requisitos mínimos del SDK de Navigation.
2. Prepárate
Si aún no tienes una cuenta de Google Cloud Platform y un proyecto con la facturación habilitada, configura tu proyecto de Google Cloud siguiendo las instrucciones de Cómo comenzar a utilizar Google Maps Platform https://developers.google.com/maps/gmp-get-started
Selecciona tu proyecto de Google Cloud en la consola.
En Cloud Console, haz clic en el menú desplegable del proyecto y selecciona el proyecto que deseas usar para este codelab.
Habilita el SDK de Navigation en tu proyecto
Habilita las API y los SDK de Google Maps Platform necesarios para este codelab en Google Cloud Marketplace.
Navega a APIs y servicios > Biblioteca en la consola de Google Cloud y busca "SDK de Navigation".
Deberías ver un resultado de la búsqueda.
Haz clic en el resultado del SDK de Navigation para abrir la página de detalles del producto. Haz clic en el botón Habilitar para habilitar el SDK en tu proyecto.
Repite este proceso para el SDK de Google Maps para Android.
Crea una clave de API
Genera una clave de API en la página Credenciales de Cloud Console. Puedes seguir los pasos del paso 3 de la sección de la guía de inicio rápido en Cómo comenzar a usar Google Maps Platform. Todas las solicitudes a Google Maps Platform requieren una clave de API.
3. Obtén los archivos de proyecto de muestra
En esta sección, se describe cómo configurar un proyecto básico y vacío de Android Studio clonando archivos del repositorio de GitHub para este codelab. El repositorio de GitHub contiene versiones anteriores y posteriores del código del codelab. El codelab comenzará con una plantilla de proyecto vacía y se compilará hasta el estado finalizado. Si te quedas atascado, puedes usar el proyecto terminado en el repositorio como referencia.
Clona este repositorio de GitHub para obtener el código necesario para este codelab.
git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git
Si no tienes instalado git, haz clic en este botón para obtener el código:
Para que puedas comenzar lo más rápido posible, el repo contiene código de partida en la carpeta Starter
que te ayudará a seguir este codelab. El proyecto inicial proporciona una IU de app y una configuración de compilación básicas, pero no tiene el SDK de Navigation agregado. También hay un proyecto Solution
terminado en caso de que quieras avanzar o consultar tu progreso en cualquier momento.
Abre el repositorio clonado en Android Studio
Una vez que hayas clonado el repositorio de forma local, usa Android Studio para abrir la carpeta Starter
como un proyecto existente.
- En el diálogo Welcome to Android Studio, haz clic en el botón Open.
- Navega a la carpeta en la que guardaste el repositorio clonado y selecciona la carpeta
Starter
dentro de la carpeta de nivel superior "codelab-navigation-101-android-kotlin
". - Verifica que el proyecto se compile y ejecute.
Agrega un dispositivo virtual o conecta un dispositivo de hardware
Para conectar un dispositivo Android a tu computadora, sigue las instrucciones de Android Studio para ejecutar apps en un dispositivo de hardware. También puedes configurar un dispositivo virtual con el Administrador de dispositivos virtuales de Android (AVD). Cuando elijas un emulador, asegúrate de seleccionar una imagen que incluya las APIs de Google.
En Android Studio, haz clic en la opción Ejecutar del menú o en el ícono del botón de reproducción. Selecciona un dispositivo según se solicite.
4. Agrega el SDK de Navigation a tu app
Agrega la biblioteca del SDK de Navigation y tu clave de API a tu proyecto
Para agregar la biblioteca del SDK de Navigation a tu app, debes modificar el build.gradle.kts
de nivel de la app para recuperar el SDK de Navigation del repositorio de Maven de Google y configurar un número de versión.
Crea una variable en la configuración de compilación para almacenar el número de versión del SDK de Navigation.
Configura una variable en tu build.gradle.kts
a nivel de la app para que contenga el valor de la versión del SDK de Navigation que se usa en tu app, de modo que sea fácil cambiar a la versión más reciente en el futuro.
Consulta las notas de la versión del SDK de Navigation para conocer el número de versión más reciente.
val navSdkVersion by extra("6.0.0")
También puedes modificar los valores de esta y otras variables usando el diálogo que se encuentra en Archivo > Estructura del proyecto > Variables:
Agrega una dependencia a la configuración de compilación
Ahora, agrega la siguiente dependencia de API al bloque de dependencias en el archivo build.gradle.kts.
del nivel de la app. La versión que se usará será el valor de ${navSdkVersion}
que acabas de establecer en el archivo build.gradle.kts
del nivel de la app:
dependencies {
// Include the Google Navigation SDK.
api("com.google.android.libraries.navigation:navigation:${navSdkVersion}")
...
Agrega tu clave de API
Usa el complemento Secrets Gradle para administrar la clave de API
Te recomendamos que uses el complemento Secrets Gradle para administrar la clave de API de forma segura en tu app. Se agregó el complemento a la plantilla inicial del proyecto como una dependencia en tu archivo build.gradle.kts
de nivel 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
}
Abre el archivo secrets.properties
en tu directorio de nivel superior y, luego, reemplaza YOUR_API_KEY
por tu clave de API. Almacena tu clave en este archivo, ya que secrets.properties
no se registra en un sistema de control de versión.
MAPS_API_KEY=YOUR_API_KEY
Para obtener más información sobre este tema, consulta Cómo agregar la clave de API a tu app en la documentación del SDK de Navigation.
Verifica el contenido de local.defaults.properties
El proyecto vacío también contiene un archivo local.defaults.properties
en tu directorio de nivel superior, en la misma carpeta que el archivo secrets.properties
. Ábrelo y observa el siguiente código.
MAPS_API_KEY=DEFAULT_API_KEY
Esto existe para proporcionar un valor de copia de seguridad para la propiedad MAPS_API_KEY
en caso de que no se agregue secrets.properties
al proyecto, de modo que no fallen las compilaciones. No es necesario editar este archivo. Si no se encuentra la definición secrets.properties
de MAPS_API_KEY
, el valor predeterminado detendrá la ejecución de la app en el tiempo de ejecución y se mostrará un error de clave de API.
Verifica que el manifiesto de Android use la clave de API que especificaste
Abre app/src/main/AndroidManifest.xml. Notarás que la propiedad MAPS_API_KEY
se usa para establecer la clave de API para la aplicación:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
Abre el archivo build.gradle.kts
de nivel de la app y busca la propiedad secrets
.
El parámetro propertiesFileName
del complemento debe establecerse como secrets.properties
, y defaultPropertiesFileName
debe mostrar 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"
}
Guarda todos los archivos y sincroniza tu proyecto con Gradle.
5. Cómo configurar los permisos de la app y agregar una IU básica
Cómo solicitar el permiso de ubicación precisa
El SDK de Navigation depende de las señales de GPS para funcionar, por lo que tu app deberá pedirle al usuario que otorgue acceso a datos de ubicación precisa. Agrega el permiso para acceder a la ubicación precisa como elemento secundario del elemento <manifest>
en 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>
Puedes obtener más información sobre los permisos de ubicación de Android en la sección Cómo solicitar permisos de ubicación de la documentación para desarrolladores de Android.
Para ejecutar tu app en un dispositivo con Android 14, solicita el permiso de ubicación de servicio en primer plano agregando la siguiente etiqueta uses-permission
en la misma ubicación que el permiso de acceso a la ubicación precisa:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
Cómo agregar una actividad de inicio con una IU básica
Cuando se ejecute tu app, necesitará código que se ejecute durante el inicio para verificar si el usuario otorgó permiso para acceder a su ubicación y controlar cada situación posible solicitando permiso si aún no se otorgó. Para ello, agrega una interfaz de usuario básica a tu app. En este codelab, se usa la IU que se genera cuando creas una nueva actividad de Views vacía en Android Studio. Adaptarás esto para realizar la verificación del permiso de ubicación antes de agregar código a la actividad para la IU de navegación.
Abre el archivo MainActivity.kt
en el editor de código y, luego, inspecciona el código, que muestra una IU básica.
Cómo solicitar permisos de acceso a la ubicación en el tiempo de ejecución
Tu app deberá activar la solicitud para acceder a la ubicación precisa antes de que se inicialice el SDK de Navigation.
Para asegurarte de que esta verificación se realice cuando se inicie tu app, agrega código a la clase MainActivity
, en el método onCreate()
anulado de tu actividad.
El siguiente código verifica si el usuario otorgó el permiso de ubicación precisa. De lo contrario, solicita el permiso. Agrega este código a tu 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
Agrega una función nueva a tu clase MainActivity
, llamada onLocationPermissionGranted
, que controlará el resultado cuando el usuario otorgue permiso para compartir su ubicación. En los próximos pasos, agregaremos código aquí para iniciar una nueva actividad de navegación.
private fun onLocationPermissionGranted() {
//code to initialize Navigation SDK will go here
}
Compila tu proyecto. Si encuentras errores de compilación, búscalos y corrígelos.
Ejecuta tu proyecto en un dispositivo virtual nuevo. Deberías ver el diálogo de solicitud de permiso cuando la app se instale y se inicie.
6. Cómo agregar una interfaz de usuario de navegación
Existen dos maneras de agregar una IU de Navigation: SupportNavigationFragment
o NavigationView
.
Para simplificar, el codelab usa un NavigationView
.
Edita el diseño
Edita res/layout/activity_main.xml
para agregar un diseño para un elemento NavigationView.
- Abre el archivo y cambia a Vista de código.
- Reemplaza todo el contenido del archivo por un nuevo diseño de
NavigationView
dentro de unRelativeLayout
, como en el siguiente ejemplo. Como solo agregarás una vista de navegación a la app, bastará con un diseño simple. - Asigna a tu NavigationView un ID de "
@+id/navigation_view
".
<?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>
Configura la actividad de Navigation
En Android Studio, abre el archivo MainActivity.kt en el editor.
Agrega código de configuración básico para garantizar que la experiencia de navegación funcione correctamente en tu app. En el archivo MainActivity.kt, realiza los siguientes cambios:
- Declara una variable en la clase
MainActivity
para hacer referencia a tuNavigationView
:
private lateinit var navView: NavigationView
- Agrega código al método
onCreate()
para obtener una referencia a tuNavigationView
:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
- Agrega código al método
onCreate()
para asegurarte de que la pantalla permanezca encendida durante la guía de navegación:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
- Edita el código que llama a
ViewCompat.setOnApplyWindowInsetsListener
para hacer referencia al ID de tuNavigationView
.
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
}
- Agrega un método
showToast()
a la clase para mostrar comentarios al usuario:
private fun showToast(errorMessage: String) {
Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG).show()
}
7. Inicializa el SDK de Navigation
Ahora que completaste la configuración básica de la actividad de Navigation, puedes inicializar el SDK de Navigation. Para ello, agrega el siguiente código a tu archivo 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")
}
}
},
)
}
Este código crea un método nuevo llamado initializeNavigationApi()
. Este método obtiene una referencia a un objeto Navigator
llamando a NavigationApi.getNavigator()
y, luego, implementa un NavigatorListener
para controlar la devolución de llamada.
Ten en cuenta que, cuando se inicialice la API de Navigation, se invocará el método NavigationListener.onNavigatorReady
, con un objeto Navigator
que se pasa como parámetro. El código anterior actualizará la variable mNavigator
que declaraste antes con el objeto Navigator
inicializado que se pasa a este método.
Por último, agrega una llamada a tu método initializeNavigationApi
desde el método onLocationPermissionGranted
.
private fun onLocationPermissionGranted() {
initializeNavigationApi()
}
8. Agrega objetos de escucha para eventos de navegación clave
Cuando los usuarios sigan las indicaciones, el SDK de Navigation activará eventos que pueden notificar a la app sobre cambios de estado clave en el proceso, como cuando el usuario se desvía o llega a su destino. En el archivo MainActivity.kt, agrega objetos de escucha para controlar estos eventos:
- Dentro de la clase
MainActivity
, declara dos variables para hacer referencia a objetos de objetos de escucha de eventos:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
- Agrega un método
registerNavigationListeners()
para configurar los objetos de escucha cuando se inicialice Navigator. Este método llama aNavigator.clearDestinations()
para restablecerNavigationView
cuando se activa el evento de llegada:
/**
* 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)
}
}
- Agrega una llamada a
registerNavigationListeners()
desde el código de devolución de llamadaonNavigatorReady
en el métodoinitializeNavigationApi
:
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
//listen for events en route
registerNavigationListeners()
}
- Configura la interfaz de usuario. Puedes controlar varios aspectos de la interfaz de usuario de navegación cuando se ejecuta la guía. Una personalización importante es la posición de la cámara. Agrega una llamada al método
setTaskRemovedBehaviour
del objetonavigator
que se muestra enonNavigatorReady
de la siguiente manera. Esto finalizará la guía y la notificación si se desliza la app:
// 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)
- Agrega una llamada a
GoogleMap.followMyLocation
para especificar unCameraPerspective
. Se puede acceder aGoogleMap
a través del métodoNavigatorView.getMapAsync()
de la siguiente manera:
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
- Para garantizar que la navegación funcione sin problemas durante el ciclo de vida de la app, implementa los siguientes métodos en tu clase
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. Establece un destino
Ya está todo listo para establecer un destino y comenzar la guía de navegación. En el archivo MainActivity.kt, realiza los siguientes cambios:
- Agrega un nuevo método
navigateToPlace()
que establezca el destino de navegación y acepte un parámetroplaceId
.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {
}
- En tu método
navigateToPlace()
, usaWaypoint.builder()
para crear unWaypoint
a partir del ID de lugar que se pasó al método. Controla elUnsupportedPlaceIdException
que puede generar esta situación en el caso de que el ID de lugar no se resuelva en una dirección precisa:
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
}
- Agrega el siguiente código a tu método
navigateToPlace()
para establecer un destino con el punto de referencia:
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")
}
}
El objeto Navigator
tiene un método setDestinations()
que puede tomar una variedad de parámetros. La opción más básica es proporcionar un Waypoint
. De forma predeterminada, el medio de transporte será DRIVING
, adecuado para vehículos de 4 ruedas a motor. El método setDestinations()
muestra un objeto ListenableResultFuture
que contiene un objeto RouteStatus
. RouteStatus
indicará si se encontró una ruta hacia el destino y te permitirá controlar varios estados de error si no es así.
- Realiza cambios de configuración adicionales para mejorar la experiencia del usuario de navegación:
// 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)
)
}
Estos cambios incluyen las siguientes mejoras:
- Se oculta la barra de acción para maximizar el espacio de la IU de Navigation.
- Habilita las indicaciones por audio para las alertas habladas y las instrucciones de navegación.
- Configurar el simulador para la depuración mediante la especificación de un multiplicador de velocidad.
- Busca un ID de lugar que actuará como destino. Lo ideal sería que no estuviera demasiado lejos de la ubicación del usuario. Usa la utilidad Buscador de IDs de lugares de Google Maps Platform o obtén un ID de lugar a partir de una llamada a la API de Places.
Si simulas la navegación, puedes establecer la ubicación del usuario en el código o tomarla de tu dispositivo conectado. En el codelab, se dará por sentado que estás simulando una ubicación en Londres, Reino Unido.
- Agrega un objeto complementario a tu clase
MainActivity
para almacenar una ubicación de inicio y un ID de lugar. El codelab usará una ubicación de partida en Londres y el ID de lugar de Trafalgar Square:
companion object{
const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
val startLocation = LatLng(51.345678, -0.1234456)
}
- Agrega una llamada a tu método
navigateToPlace()
desde la devolución de llamadaonNavigatorReady
dentro del métodoinitializeNavigationApi
y agrega una rama de la lógica que se ejecutará en el modo de depuración y que establezca la ubicación del usuario:
// 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. Compila y ejecuta tu código
La primera vez que ejecutes la app, deberás otorgarle permisos de ubicación y aceptar las condiciones de uso del SDK de Navigation.
Nota: Cuando ejecutes la app, se llamará al método setDestinations(), que genera un cargo después de que se usen los primeros 1,000 destinos. Consulta Uso y facturación para obtener más información.
Cómo configurar la ubicación
De forma predeterminada, el dispositivo emulado puede tener su ubicación establecida en el campus de Google en Mountain View, California, a menos que hayas establecido una ubicación en el código o usando el diálogo de propiedades del emulador.
Si es así, es posible que la app no encuentre una ruta hacia el ID de lugar que configuraste (de forma predeterminada, la Ópera de Sídney, Sídney, Australia). Tu método showToast()
lo indicará con el mensaje "No route found".
Cómo codificar de forma fija la ubicación de partida
Para establecer una ubicación diferente en el código, agrega la siguiente línea a tu método navigateToPlace()
en MainActivity.kt, antes de la llamada a mNavigator.startGuidance()
:
mNavigator?.simulator?.setUserLocation(startLocation)
Cómo iniciar el emulador en la ubicación predeterminada que elijas
Para establecer una ubicación diferente en el emulador del dispositivo, inícialo si aún no se está ejecutando y haz clic en el menú de 3 puntos con la información sobre la herramienta "Extended Controls". El cuadro de diálogo que se abre tiene una opción de menú para "Ubicación".
Por ejemplo, si utilizas el ID de lugar de la Ópera de Sídney como destino, elige una ubicación en Sídney, Australia. Por ejemplo, busca "playa Bondi", selecciona una sugerencia y haz clic en "Guardar ubicación" en la parte inferior derecha del diálogo. También puedes hacer clic en "Guardar punto" para agregar la ubicación a una lista guardada para usarla en el futuro.
Si estableces un ID de Place diferente como destino, elige una ubicación cercana para que la ruta simulada sea realista y no demasiado larga para facilitar la depuración.
Reinicia la app, que ahora debería navegar al destino.
11. ¡Felicitaciones!
Completaste este codelab. ¡Felicitaciones! Llegaste a tu destino. ¡Diviértete programando! :-)
12. Más información
Si quieres llevar el desarrollo de tu app más allá, echa un vistazo a los siguientes temas para inspirarte.
- Escucha más eventos de navegación. Agrega un código para mostrar un mensaje si el conductor vuelve a la ruta o cuando llega.
- Personaliza la interfaz de navegación.
- Si quieres un desafío más grande, intenta agregar un control de selector de lugares de la API de Places para permitir que el usuario establezca el destino. Sugerencia: Las apps de demostración del SDK de Navigation en GitHub tienen una implementación de ejemplo.
- Para evitar posibles problemas al llamar a los objetos Navigator y GoogleMap de forma asíncrona, adopta el enfoque que se usa en las apps de demostración del SDK de Navigation en GitHub. En situaciones de apps más complejas, es posible que estos objetos no hayan terminado de inicializarse cuando se ejecuta el código. Sugerencia: Puedes agregar la clase InitializedNavScope al final de tu archivo MainActivity.kt para una implementación muy rápida.