Создайте простое навигационное приложение для Android с помощью SDK навигации платформы Google Maps.

1. Прежде чем начать

В этом практическом занятии вы научитесь создавать простое Android-приложение, использующее SDK Google Maps Platform Navigation для навигации к заранее заданному пункту назначения.

Вот как будет выглядеть ваше приложение после завершения работы.

b6c535afde7abd20.png

Предварительные требования

  • Знание основ разработки Android-приложений на Kotlin.
  • Некоторые знания основных концепций Google Maps SDK, таких как карты, местоположения, координаты.

Что вы узнаете

  • Как создать простое Android-приложение, использующее Navigation SDK для навигации к месту назначения.
  • Как интегрировать SDK навигации из удалённого репозитория Google Maven
  • Как управлять разрешениями на доступ к местоположению и пользовательским соглашением в рамках условий использования Navigation SDK для конечных пользователей.
  • Как инициализировать SDK
  • Как задать пункт назначения и запустить навигационное сопровождение.

Что вам понадобится

  • Установлена ​​последняя стабильная версия Android Studio. Данный практический пример создан с использованием Android Studio Jellyfish. Если вы используете другую версию, внешний вид и расположение элементов интерфейса и компонентов могут отличаться.
  • Учетная запись Google и проект с включенной функцией оплаты.
  • Устройство Android в режиме разработчика с включенной отладкой по USB или эмулятор Android. В любом случае, устройство должно соответствовать минимальным требованиям для Navigation SDK.

2. Настройка

Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенной оплатой, настройте свой проект Google Cloud, следуя инструкциям по началу работы с Google Maps Platform : https://developers.google.com/maps/gmp-get-started

Выберите свой проект Google Cloud в консоли.

В консоли Cloud Console щелкните раскрывающееся меню «Проект» и выберите проект, который вы хотите использовать для этого практического занятия.

Выпадающее меню выбора проекта в консоли Google Cloud.

Включите SDK навигации в вашем проекте.

Для выполнения этого практического задания необходимо включить API и SDK платформы Google Maps в Google Cloud Marketplace .

Перейдите в раздел API и сервисы > Библиотека в консоли Google Cloud и найдите "Navigation SDK".

Вы должны увидеть один результат поиска.

Экран библиотеки API в консоли Google Cloud, отображающий страницу Navigation SDK.

Нажмите на результат поиска «Navigation SDK», чтобы открыть страницу с подробной информацией о продукте. Нажмите кнопку «Включить», чтобы активировать SDK в вашем проекте.

Повторите этот процесс для Google Maps SDK для Android .

Создайте ключ API

Сгенерируйте ключ API на странице «Учетные данные» в Cloud Console. Вы можете выполнить действия, описанные в шаге 3 раздела «Быстрый старт» в руководстве «Начало работы с Google Maps Platform» . Для всех запросов к Google Maps Platform требуется ключ API.

3. Получите файлы примера проекта.

В этом разделе описывается, как создать базовый пустой проект Android Studio, клонировав файлы из репозитория GitHub для этого практического занятия. Репозиторий GitHub содержит версии кода для практического занятия до и после его завершения. Практическое занятие начнется с пустого шаблона проекта и будет постепенно доходить до конечного состояния. Вы можете использовать готовый проект из репозитория в качестве образца, если у вас возникнут трудности.

Клонируйте этот репозиторий на GitHub, чтобы получить код для этого практического занятия.

git clone https://github.com/googlemaps-samples/codelab-navigation-101-android-kotlin.git

Если у вас не установлен Git, нажмите эту кнопку, чтобы получить код:

Чтобы вы могли как можно быстрее начать работу, в репозитории в папке Starter содержится некоторый стартовый код, который поможет вам следовать инструкциям в этом практическом занятии. Стартовый проект предоставляет базовый пользовательский интерфейс приложения и конфигурацию сборки, но в него не добавлен SDK навигации. Также есть готовый проект Solution , если вы захотите перейти к следующему этапу или проверить свой прогресс в любое время.

Откройте клонированный репозиторий в Android Studio.

После клонирования репозитория локально, используйте Android Studio, чтобы открыть папку Starter как существующий проект.

  1. В диалоговом окне «Добро пожаловать в Android Studio» нажмите кнопку «Открыть».
  2. Перейдите в папку, где вы сохранили клонированный репозиторий, и выберите папку Starter , расположенную в корневой папке " codelab-navigation-101-android-kotlin ".
  3. Убедитесь, что проект собирается и запускается.

Добавьте виртуальное устройство или подключите аппаратное устройство.

Чтобы подключить устройство Android к компьютеру, следуйте инструкциям Android Studio по запуску приложений на аппаратном устройстве . В качестве альтернативы вы можете настроить виртуальное устройство с помощью менеджера виртуальных устройств Android (AVD) . При выборе эмулятора убедитесь, что вы выбрали образ, включающий API Google.

В Android Studio нажмите пункт меню «Выполнить» или значок кнопки воспроизведения. Выберите устройство согласно подсказке.

4. Добавьте SDK навигации в ваше приложение.

Добавьте библиотеку Navigation SDK и свой API-ключ в свой проект.

Чтобы добавить библиотеку Navigation SDK в ваше приложение, необходимо изменить build.gradle.kts на уровне приложения , чтобы он загружал Navigation SDK из репозитория Google Maven и указывал номер версии.

Создайте переменную в конфигурации сборки для хранения номера версии Navigation SDK.

Создайте переменную в файле build.gradle.kts на уровне приложения, чтобы она содержала значение версии Navigation SDK, используемой в вашем приложении, и позволяла легко изменить ее на последнюю версию в будущем.

Для получения информации о последней версии ознакомьтесь с примечаниями к выпуску Navigation SDK .

val navSdkVersion by extra("6.0.0")

Вы также можете изменить значения этой и других переменных с помощью диалогового окна, расположенного по адресу Файл > Структура проекта > Переменные:

668332736b67dc82.png

Добавьте зависимость в конфигурацию сборки.

Теперь добавьте следующую зависимость API в блок dependencies в файле build.gradle.kts. Используемая версия будет равна значению ${navSdkVersion} , которое вы только что установили в файле build.gradle.kts вашего приложения:

dependencies {

   // Include the Google Navigation SDK.
   api("com.google.android.libraries.navigation:navigation:${navSdkVersion}")

...

Добавьте свой API-ключ

Используйте плагин Secrets Gradle для управления ключом API.

Мы рекомендуем использовать плагин Secrets Gradle для безопасного управления ключом API в вашем приложении. Плагин добавлен в исходный шаблон проекта в качестве зависимости в файле build.gradle.kts верхнего уровня.

// 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
}

Откройте файл secrets.properties в корневом каталоге и замените YOUR_API_KEY на свой API-ключ. Сохраните свой ключ в этом файле, поскольку secrets.properties не включается в систему контроля версий.

MAPS_API_KEY=YOUR_API_KEY

Для получения дополнительной информации по этой теме см. раздел «Добавление ключа API в ваше приложение» в документации Navigation SDK.

Проверьте содержимое файла local.defaults.properties.

В пустом проекте также содержится файл local.defaults.properties в корневом каталоге, в той же папке, что и файл secrets.properties . Откройте его и посмотрите на следующий код.

MAPS_API_KEY=DEFAULT_API_KEY

Этот параметр существует для обеспечения резервного значения свойства MAPS_API_KEY на случай, если файл secrets.properties не добавлен в проект, чтобы предотвратить сбои сборки. Редактировать этот файл не нужно. Если определение MAPS_API_KEY в secrets.properties не найдено, значение по умолчанию остановит работу приложения во время выполнения с ошибкой ключа API.

Убедитесь, что в Android Manifest используется указанный вами ключ API.

Откройте файл app/src/main/AndroidManifest.xml. Вы заметите, что свойство MAPS_API_KEY используется для установки ключа API для приложения:

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

Откройте файл build.gradle.kts на уровне приложения и найдите свойство secrets .

Параметр propertiesFileName плагина должен быть установлен на secrets.properties , а defaultPropertiesFileName — на 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"
}

Сохраните все файлы и синхронизируйте свой проект с Gradle.

5. Настройте разрешения приложения и добавьте базовый пользовательский интерфейс.

Запросить разрешение на определение точного местоположения.

Для работы Navigation SDK необходимы сигналы GPS, поэтому вашему приложению потребуется запросить у пользователя разрешение на доступ к точным данным о местоположении. Добавьте разрешение на доступ к точным данным о местоположении в качестве дочернего элемента элемента <manifest> в файле 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>

Более подробную информацию о разрешениях на определение местоположения в Android можно найти в разделе «Запрос разрешений на определение местоположения» документации для разработчиков Android.

Чтобы запустить приложение на устройстве Android 14, запросите разрешение на определение местоположения для службы переднего плана, добавив следующий тег uses-permission в то же место, что и разрешение на точное определение местоположения:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

Добавьте активность запуска с базовым пользовательским интерфейсом.

При запуске вашего приложения потребуется код, который будет выполняться во время запуска, чтобы проверить, предоставил ли пользователь разрешение на доступ к своему местоположению, и обработать каждый возможный сценарий, запросив разрешение, если оно еще не было предоставлено. Для этого добавьте в приложение базовый пользовательский интерфейс. В этом практическом занятии используется интерфейс, создаваемый при создании нового пустого объекта Views в Android Studio. Вам нужно будет адаптировать его для проверки разрешения на доступ к местоположению перед добавлением кода в объект для навигации.

Откройте файл MainActivity.kt в редакторе кода и изучите код; он отображает базовый пользовательский интерфейс.

Запросить права доступа к местоположению во время выполнения.

Вашему приложению потребуется инициировать запрос на получение точного местоположения до инициализации SDK навигации.

Чтобы гарантировать выполнение этой проверки при запуске приложения, добавьте некоторый код в класс MainActivity , в переопределенный метод onCreate() вашего Activity.

Следующий код проверяет, предоставил ли пользователь разрешение на определение местоположения. Если нет, он запрашивает это разрешение. Добавьте этот код внутрь метода 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

Добавьте в класс MainActivity новую функцию с именем onLocationPermissionGranted , которая будет обрабатывать результат, когда пользователь предоставит разрешение на обмен своим местоположением. На следующих шагах мы добавим сюда код для запуска новой активности навигации.

private fun onLocationPermissionGranted() {
   //code to initialize Navigation SDK will go here
}

Соберите свой проект. Если возникнут ошибки сборки, найдите и исправьте их.

Запустите свой проект на новом виртуальном устройстве. После установки и запуска приложения должно появиться диалоговое окно запроса разрешений.

6. Добавить навигационный пользовательский интерфейс.

Добавить элемент навигации можно двумя способами: SupportNavigationFragment или NavigationView .

Для простоты в практическом задании используется NavigationView .

Изменить макет

Отредактируйте res/layout/activity_main.xml , чтобы добавить макет для NavigationView.

  1. Откройте файл и переключитесь в режим просмотра кода.
  2. Замените всё содержимое файла новым макетом, состоящим из NavigationView внутри RelativeLayout , как показано в примере ниже. Поскольку вы просто добавляете навигационное представление в приложение, подойдёт простой макет.
  3. Присвойте вашему NavigationView идентификатор " @+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>

Настройте действие навигации.

В Android Studio откройте файл MainActivity.kt в редакторе.

Добавьте базовый код настройки, чтобы обеспечить корректную работу навигации в вашем приложении. В файле MainActivity.kt внесите следующие изменения:

  1. Объявите переменную в классе MainActivity для ссылки на ваш NavigationView :
private lateinit var navView: NavigationView
  1. Добавьте в метод onCreate() код для получения ссылки на ваш NavigationView :
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
  1. Добавьте в метод onCreate() код, который гарантирует, что экран останется включенным во время навигации:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  1. Отредактируйте код, вызывающий ViewCompat.setOnApplyWindowInsetsListener , чтобы он ссылался на идентификатор вашего 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. Добавьте в класс метод showToast() для отображения обратной связи пользователю:
private fun showToast(errorMessage: String) {
   Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG).show()
}

7. Инициализация SDK навигации

Теперь, когда вы завершили базовую настройку навигационной активности, вы можете инициализировать SDK навигации. Для этого добавьте следующий код в файл 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")
               }
           }
       },
   )

}

Этот код создает новый метод с именем initializeNavigationApi() . Этот метод получает ссылку на объект Navigator , вызывая NavigationApi.getNavigator() , и реализует интерфейс NavigatorListener для обработки обратного вызова.

Обратите внимание, что при инициализации API навигации будет вызван метод NavigationListener.onNavigatorReady , которому в качестве параметра будет передан объект Navigator . Приведенный выше код обновит объявленную ранее переменную mNavigator инициализированным объектом Navigator , переданным этому методу.

Наконец, добавьте вызов метода initializeNavigationApi из метода onLocationPermissionGranted .

private fun onLocationPermissionGranted() {
   initializeNavigationApi()
}

8. Добавьте обработчики событий для ключевых событий навигации.

Когда пользователи следуют указаниям, SDK навигации будет генерировать события, которые могут уведомлять приложение об изменениях ключевых состояний в пути, например, когда пользователь меняет маршрут или прибывает в пункт назначения. В файле MainActivity.kt добавьте обработчики этих событий:

  1. Внутри класса MainActivity объявите две переменные для ссылки на объекты обработчиков событий:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
  1. Добавьте метод registerNavigationListeners() для настройки слушателей событий при инициализации навигатора. Этот метод вызывает Navigator.clearDestinations() для сброса NavigationView при срабатывании события 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. Добавьте вызов функции registerNavigationListeners() из кода обратного вызова onNavigatorReady в метод initializeNavigationApi :
override fun onNavigatorReady(navigator: Navigator) {
   // store a reference to the Navigator object
   mNavigator = navigator

   //listen for events en route
   registerNavigationListeners()


}
  1. Настройте пользовательский интерфейс. Вы можете управлять различными аспектами интерфейса навигации во время работы подсказок. Одна из важных настроек — положение камеры. Добавьте вызов метода setTaskRemovedBehaviour объекта navigator , возвращаемого в onNavigatorReady , следующим образом. Это прекратит показ подсказок и уведомлений, если приложение будет смахнуто:
// 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. Добавьте вызов метода GoogleMap.followMyLocation , чтобы указать CameraPerspective . Доступ к GoogleMap осуществляется через метод NavigatorView.getMapAsync() следующим образом:
navView.getMapAsync {
   googleMap  ->
   googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
  1. Для обеспечения бесперебойной навигации на протяжении всего жизненного цикла приложения реализуйте следующие методы в классе 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. Укажите пункт назначения

Теперь вы готовы задать пункт назначения и запустить навигацию. В файле MainActivity.kt внесите следующие изменения:

  1. Добавьте новый метод navigateToPlace() , который задает пункт назначения навигации и принимает параметр placeId .
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {

}
  1. В методе navigateToPlace() используйте метод Waypoint.builder() для создания Waypoint на основе идентификатора места, переданного в метод. Обработайте исключение UnsupportedPlaceIdException , которое может быть сгенерировано в ситуациях, когда идентификатор места не соответствует точному адресу:
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. Добавьте следующий код в метод navigateToPlace() , чтобы задать пункт назначения с помощью путевой точки:
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")
   }
}

Объект Navigator имеет метод setDestinations() , который может принимать различные параметры. Самый простой вариант — указать Waypoint ). По умолчанию это будет режим движения DRIVING , подходящий для автомобилей. Метод setDestinations() возвращает объект ListenableResultFuture , содержащий объект RouteStatus . Объект RouteStatus будет указывать, был ли найден маршрут до пункта назначения, и позволит обрабатывать различные состояния ошибок, если маршрут не найден.

  1. Внесите дополнительные изменения в конфигурацию для улучшения пользовательского опыта навигации:
// 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)
   )
}

Эти изменения включают в себя следующие улучшения:

  • Скрытие панели действий для максимального увеличения пространства для навигационного интерфейса.
  • Включение функции голосового сопровождения для озвучивания предупреждений и навигационных инструкций.
  • Настройка симулятора для отладки путем указания множителя скорости.
  1. Найдите идентификатор места (Place ID), который будет служить пунктом назначения. В идеале это место должно находиться не слишком далеко от местоположения пользователя. Используйте утилиту поиска идентификаторов мест на платформе Google Maps или получите идентификатор места из вызова API мест.

Если вы имитируете навигацию, вы можете задать местоположение пользователя в коде или получить его с подключенного устройства. В практическом задании предполагается, что вы имитируете местоположение в Лондоне, Великобритания.

  1. Добавьте в класс MainActivity дополнительный объект для хранения начальной точки и идентификатора места. В практическом задании будет использоваться начальная точка в Лондоне и идентификатор Трафальгарской площади:
companion object{
   const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
   val startLocation = LatLng(51.345678, -0.1234456)
}
  1. Добавьте вызов метода navigateToPlace() из коллбэка onNavigatorReady внутри метода initializeNavigationApi и добавьте ветвь логики, которая будет выполняться в режиме отладки и устанавливать местоположение пользователя:
// 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. Соберите и запустите свой код.

При первом запуске приложения вам потребуется предоставить приложению разрешение на определение местоположения и принять условия использования Navigation SDK.

Примечание: при запуске приложения будет вызван метод setDestinations(), за использование которого взимается плата после первых 1000 использованных пунктов назначения. Дополнительную информацию см. в разделе «Использование и оплата» .

93aa433000a14dfc.png

Диалоговое окно с условиями использования Navigation SDK для конечных пользователей.

Установка местоположения

По умолчанию местоположение эмулируемого устройства может быть установлено на кампус Google в Маунтин-Вью, штат Калифорния, если вы не указали местоположение в коде или с помощью диалогового окна свойств эмулятора.

В этом случае приложение может не найти маршрут к указанному вами идентификатору места (по умолчанию — Сиднейский оперный театр, Сидней, Австралия). Об этом сообщит сообщение «Маршрут не найден», которое отобразится в методе showToast() .

На карте в навигационном приложении показан офис Google в Маунтин-Вью, штат Калифорния.

Задание начального местоположения вручную

Чтобы задать другое местоположение в коде, добавьте следующую строку в метод navigateToPlace() в файле MainActivity.kt перед вызовом mNavigator.startGuidance() :

mNavigator?.simulator?.setUserLocation(startLocation)

Запуск эмулятора в выбранном вами месте по умолчанию.

Чтобы задать другое местоположение в эмуляторе устройства, запустите эмулятор, если он еще не запущен, и щелкните меню с тремя точками и всплывающей подсказкой «Расширенные элементы управления». В открывшемся диалоговом окне есть пункт меню «Местоположение».

Например, если в качестве пункта назначения используется идентификатор места «Сиднейский оперный театр», выберите местоположение в Сиднее, Австралия. Например, найдите «пляж Бонди», выберите предложенный вариант и нажмите «Сохранить местоположение» в правом нижнем углу диалогового окна. Вы также можете нажать «Сохранить точку», чтобы добавить местоположение в список сохраненных мест для дальнейшего использования.

Диалоговое окно «Расширенные элементы управления» в диспетчере устройств Android, отображающее поле выбора места и карту с центром на пляже Бонди в Австралии.

Если вы задали другой идентификатор места в качестве пункта назначения, выберите место, расположенное недалеко от него, чтобы смоделированный маршрут был реалистичным и не слишком длинным для удобства отладки.

Перезапустите приложение, и оно должно перейти к месту назначения.

Скриншот приложения «Навигация», показывающий маршрут до пункта назначения.

11. Поздравляем!

Вы успешно завершили этот практический урок. Отлично – вы достигли цели! Удачного программирования! :-)

55812f33256c0596.png

12. Дальнейшее развитие событий

Если вы хотите вывести разработку своего приложения на новый уровень, ознакомьтесь со следующими темами для вдохновения.