Compila una app de navegación simple para Android con el SDK de Navigation de Google Maps Platform

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.

b6c535afde7abd20.png

Requisitos previos

  • Conocimientos básicos sobre el desarrollo de apps para Android en Kotlin
  • Conocimientos básicos sobre los conceptos del SDK de Google Maps, como mapas, ubicaciones y coordenadas

Qué aprenderás

  • Cómo crear una app para Android simple que usa 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 varíen la apariencia y el diseño de la interfaz y los componentes.
  • 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 todavía 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.

El menú desplegable del selector de proyectos en la consola de Google Cloud.

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 "Navigation SDK".

Deberías ver un resultado de la búsqueda.

La pantalla de la biblioteca de APIs en la consola de Google Cloud, en la que se muestra la página del SDK de Navigation.

Haz clic en el resultado del SDK de Navigation para abrir la página 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 que se indican en el paso 3 de la sección de inicio rápido en Cómo comenzar a utilizar Google Maps Platform. Todas las solicitudes a Google Maps Platform requieren una clave de API.

3. Obtén los archivos del proyecto de muestra

En esta sección, se describe cómo configurar un proyecto básico vacío de Android Studio clonando archivos del repositorio de GitHub para este codelab. El repo de GitHub contiene versiones del código del codelab antes y después de la implementación. El codelab comenzará con una plantilla de proyecto vacía y se desarrollará hasta el estado final. Si te quedas atascado, puedes usar el proyecto terminado en el repo como referencia.

Clona este repo de GitHub para obtener el código de 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 inicial en la carpeta Starter que te ayudará a seguir este codelab. El proyecto de inicio proporciona una IU y una configuración de compilación básicas de la app, pero no tiene agregado el SDK de Navigation. También hay un proyecto Solution terminado en caso de que quieras adelantarte o verificar tu progreso en cualquier momento.

Abre el repositorio clonado en Android Studio

Una vez que hayas clonado el repo de forma local, usa Android Studio para abrir la carpeta Starter como un proyecto existente.

  1. En el diálogo Welcome to Android Studio, haz clic en el botón Open.
  2. Navega a la carpeta en la que guardaste el repo clonado y selecciona la carpeta Starter dentro de la carpeta de nivel superior "codelab-navigation-101-android-kotlin".
  3. 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 sobre cómo 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 del menú Run 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 archivo build.gradle a nivel de la app build.gradle.kts para recuperar el SDK de Navigation del repositorio 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 con el diálogo que se encuentra en File > Project Structure > Variables:

668332736b67dc82.png

Agrega una dependencia a la configuración de compilación

Ahora agrega la siguiente dependencia de la API al bloque de dependencias en tu archivo build.gradle.kts. a nivel de la app. La versión que se use será el valor de ${navSdkVersion} que acabas de establecer en tu archivo build.gradle.kts a 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 de Gradle para Secrets para administrar la clave de API

Te recomendamos que uses el complemento Secrets Gradle para administrar de forma segura la clave de API en tu app. El complemento se agregó 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 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 Agrega 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, 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 secrets.properties no se agregue al proyecto, de modo que no fallen las compilaciones. No es necesario editar este archivo. Si no se encuentra la definición de secrets.properties de MAPS_API_KEY, el valor predeterminado detendrá la ejecución de la app en el tiempo de ejecución, con 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. Observarás que la propiedad MAPS_API_KEY se usa para establecer la clave de API de la aplicación:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${MAPS_API_KEY}" />

Abre el archivo build.gradle.kts a nivel de la app y busca la propiedad secrets.

El parámetro de configuración propertiesFileName del complemento debe establecerse en secrets.properties, y defaultPropertiesFileName debe leer 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. Configura los permisos de la app y agrega una IU básica

Solicita permiso de ubicación precisa

El SDK de Navigation depende de los indicadores de GPS para funcionar, por lo que tu app deberá pedirle al usuario que otorgue acceso a los 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 Solicita 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 del 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" />

Agrega 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 crea cuando creas una actividad de Views nueva y 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 examina el código, que muestra una IU básica.

Solicita permisos de acceso a la ubicación en el tiempo de ejecución

Tu app deberá activar la solicitud de acceso 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 dentro de 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 tienes algún error de compilación, búscalo y corrígelo.

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. Agrega una interfaz de usuario de navegación

Existen dos maneras de agregar una IU de navegación: SupportNavigationFragment o NavigationView.

Para simplificar, el codelab usa un NavigationView.

Cómo editar el diseño

Edita res/layout/activity_main.xml para agregar un diseño a un NavigationView.

  1. Abre el archivo y cambia a la Vista de código.
  2. Reemplaza todo el contenido del archivo por un nuevo diseño de un NavigationView dentro de un RelativeLayout, como en el siguiente ejemplo. Como solo agregarás una vista de navegación a la app, un diseño simple será suficiente.
  3. Asigna a tu NavigationView el ID "@+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:

  1. Declara una variable en tu clase MainActivity para hacer referencia a tu NavigationView:
private lateinit var navView: NavigationView
  1. Agrega código al método onCreate() para obtener una referencia a tu NavigationView:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
  1. Agrega código al método onCreate() para asegurarte de que la pantalla permanezca encendida durante las indicaciones de navegación:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  1. Edita el código que llama a ViewCompat.setOnApplyWindowInsetsListener para hacer referencia al ID de tu NavigationView.
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
}
  1. 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 nuevo método 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 inicializa la API de Navigation, se invocará el método NavigationListener.onNavigatorReady, con un objeto Navigator pasado 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 al método initializeNavigationApi desde el método onLocationPermissionGranted.

private fun onLocationPermissionGranted() {
   initializeNavigationApi()
}

8. Agrega objetos de escucha para eventos de navegación clave

Cuando tus usuarios sigan las indicaciones, el SDK de Navigation activará eventos que pueden notificar a la app sobre los cambios de estado clave en ruta, por ejemplo, cuando el usuario cambie de ruta o llegue a su destino. En el archivo MainActivity.kt, agrega objetos de escucha para controlar estos eventos:

  1. Dentro de la clase MainActivity, declara dos variables para hacer referencia a los objetos de escucha de eventos:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
  1. Agrega un método registerNavigationListeners() para configurar los objetos de escucha cuando se inicialice el navegador. Este método llama a Navigator.clearDestinations() para restablecer NavigationView cuando se activa el evento Arrival:
/**
* 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)
   }
}
  1. Agrega una llamada a registerNavigationListeners() desde el código de devolución de llamada onNavigatorReady en el método initializeNavigationApi:
override fun onNavigatorReady(navigator: Navigator) {
   // store a reference to the Navigator object
   mNavigator = navigator

   //listen for events en route
   registerNavigationListeners()


}
  1. 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 objeto navigator que se devuelve en onNavigatorReady de la siguiente manera. Se finalizarán las indicaciones y las notificaciones si se desliza el dedo para cerrar 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)
  1. Agrega una llamada a GoogleMap.followMyLocation para especificar un CameraPerspective. Se accede a GoogleMap a través del método NavigatorView.getMapAsync() de la siguiente manera:
navView.getMapAsync {
   googleMap  ->
   googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
  1. Para garantizar que la navegación funcione sin problemas durante todo 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. Cómo establecer un destino

Ahora puedes establecer un destino y comenzar la guía de navegación. En el archivo MainActivity.kt, realiza los siguientes cambios:

  1. Agrega un nuevo método navigateToPlace() que establezca el destino de navegación y acepte un parámetro placeId.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {

}
  1. En tu método navigateToPlace(), usa el método Waypoint.builder() para crear un objeto Waypoint a partir del ID de lugar que se pasó al método. Controla el UnsupportedPlaceIdException que puede arrojar, para situaciones en las que el ID de lugar no se resuelve 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
}
  1. 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, se establecerá el modo de viaje DRIVING, adecuado para automóviles de 4 ruedas. El método setDestinations() devuelve un objeto ListenableResultFuture que contiene un objeto RouteStatus. El objeto RouteStatus indicará si se encontró una ruta al destino y te permitirá controlar varios estados de error si no se encontró una.

  1. 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 acciones para maximizar el espacio de la IU de navegación.
  • Habilita la guía de audio para que se reproduzcan alertas e instrucciones de navegación.
  • Configura el simulador para la depuración especificando un multiplicador de velocidad.
  1. Busca un ID de lugar que actúe como tu destino. Lo ideal sería que no esté demasiado lejos de la ubicación del usuario. Usa la utilidad de Place ID Finder de Google Maps Platform o bien 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 supondrá que simulas una ubicación en Londres, Reino Unido.

  1. Agrega un objeto complementario a tu clase MainActivity para almacenar una ubicación de inicio y un ID de lugar. En el codelab, se usará una ubicación de inicio 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)
}
  1. Agrega una llamada a tu método navigateToPlace() desde la devolución de llamada onNavigatorReady dentro del método initializeNavigationApi y agrega una rama de lógica que se ejecutará en el modo de depuración y que establecerá 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(), lo que generará un cargo después de los primeros 1,000 destinos utilizados. Consulta Uso y facturación para obtener más información.

93aa433000a14dfc.png

Es el diálogo de las condiciones del servicio para el usuario final del SDK de Navigation.

Cómo establecer la ubicación

De forma predeterminada, es posible que la ubicación del dispositivo emulado esté establecida en el campus de Google en Mountain View, California, a menos que hayas establecido una ubicación en el código o con el diálogo de propiedades del emulador.

Si es así, es posible que la app no pueda encontrar una ruta al ID de lugar que configuraste (de forma predeterminada, la Ópera de Sídney, Sídney, Australia). Esto se indicará con un mensaje que diga "No se encontró ninguna ruta", que mostrará tu método showToast().

La vista de mapa de la app de Navegación que muestra la oficina de Google en Mountain View, California.

Codificación de la ubicación de inicio

Para establecer una ubicación diferente en el código, agrega la siguiente línea en tu método navigateToPlace() en MainActivity.kt, antes de la llamada a mNavigator.startGuidance():

mNavigator?.simulator?.setUserLocation(startLocation)

Cómo iniciar el emulador en una ubicación predeterminada de tu elección

Para establecer una ubicación diferente en el emulador de dispositivo, inícialo si aún no se está ejecutando y haz clic en el menú de 3 puntos con la sugerencia "Controles extendidos". El diálogo que se abre tiene una opción de menú para "Ubicación".

Por ejemplo, si usas el ID de lugar de la Ópera de Sídney como destino, elige una ubicación en Sídney, Australia. Por ejemplo, busca "Bondi Beach", 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 y usarla en el futuro.

El diálogo Extended Controls en el Administrador de dispositivos de Android, que muestra un selector de lugares y un mapa centrado en la playa de Bondi en Australia.

Si estableces un ID de lugar 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. Ahora debería navegar al destino.

Una captura de pantalla de la app de Navegación que brinda indicaciones para llegar al destino.

11. ¡Felicitaciones!

Completaste este codelab. ¡Bien hecho! Llegaste a tu destino. ¡Feliz programación! :-)

55812f33256c0596.png

12. Profundiza tus conocimientos

Si deseas llevar el desarrollo de tu app más allá, consulta los siguientes temas para inspirarte.