Tworzenie prostej aplikacji nawigacyjnej na Androida za pomocą pakietu SDK nawigacji Google Maps Platform

1. Zanim zaczniesz

W tym ćwiczeniu w Codelab dowiesz się, jak utworzyć prostą aplikację na Androida, która korzysta z pakietu SDK nawigacji platformy Google Maps do nawigacji do wstępnie skonfigurowanego miejsca docelowego.

Tak będzie wyglądać Twoja aplikacja po zakończeniu pracy.

b6c535afde7abd20.png

Wymagania wstępne

  • Wiedza z zakresu podstawowych aplikacji na Androida w Kotlin
  • Dobra znajomość podstawowych pojęć związanych z pakietem SDK Map Google, takich jak mapy, lokalizacje czy współrzędne.

Czego się nauczysz

  • Jak utworzyć prostą aplikację na Androida, która korzysta z pakietu SDK nawigacji do nawigacji do miejsca docelowego.
  • Jak zintegrować pakiet Navigation SDK ze zdalnego repozytorium Google Maven
  • Jak zarządzać uprawnieniami do lokalizacji i umową użytkownika w ramach warunków korzystania z usługi w pakiecie SDK nawigacji
  • Jak zainicjować pakiet SDK
  • Jak ustawić miejsce docelowe i uruchomić nawigację.

Czego potrzebujesz

  • Zainstalowana najnowsza stabilna wersja Android Studio. To ćwiczenie z programowania zostało utworzone w Android Studio Jellyfish. Jeśli używasz innej wersji, wygląd i układ interfejsu i komponentów mogą się różnić.
  • konto Google i projekt z włączonymi płatnościami.
  • urządzenie z Androidem w trybie programisty z włączonym debugowaniem przez USB lub emulator Androida, Niezależnie od tego, który z nich wybierzesz, musi on spełniać minimalne wymagania pakietu Navigation SDK.

2. Konfiguracja

Jeśli nie masz jeszcze konta Google Cloud Platform ani projektu z włączonym rozliczeniem, skonfiguruj projekt Google Cloud zgodnie z instrukcjami Rozpoczynanie pracy z Google Maps Platform https://developers.google.com/maps/gmp-get-started

Wybierz swój projekt Google Cloud w konsoli.

W konsoli Google Cloud kliknij menu projektu i wybierz projekt, którego chcesz użyć w tym CodeLab.

Menu selektora projektu w konsoli Google Cloud.

Włączanie pakietu SDK Nawigacji w projekcie

Włącz interfejsy API i pakiety SDK Google Maps Platform wymagane do wykonania tego ćwiczenia z programowania w Google Cloud Marketplace.

W konsoli Google Cloud przejdź do sekcji Interfejsy API i usługi > Biblioteka i wyszukaj „Navigation SDK”.

Powinien pojawić się 1 wynik wyszukiwania.

Ekran biblioteki interfejsów API w konsoli Google Cloud ze stroną Navigation SDK.

Kliknij wynik pakietu Navigation SDK, aby otworzyć stronę Szczegóły produktu. Kliknij przycisk Włącz, aby włączyć pakiet SDK w projekcie.

Powtórz ten proces w przypadku pakietu Google Maps SDK na Androida.

Tworzenie klucza interfejsu API

Wygeneruj klucz interfejsu API na stronie Dane logowania w konsoli Cloud. Możesz wykonać czynności opisane w kroku 3 w sekcji Szybki start w artykule Pierwsze kroki z Google Maps Platform. Wszystkie żądania wysyłane do Google Maps Platform wymagają klucza interfejsu API.

3. Pobieranie przykładowych plików projektu

W tej sekcji opisano, jak skonfigurować podstawowy pusty projekt Android Studio przez sklonowanie plików z repozytorium GitHub na potrzeby tego ćwiczenia z programowania. Repozytorium GitHub zawiera wersje kodu ćwiczeń z programowania przed i po. Codelab rozpocznie się od pustego szablonu projektu, a potem będzie się rozwijać aż do gotowego stanu. Jeśli utkniesz, możesz użyć gotowego projektu w repozytorium jako odniesienia.

Aby uzyskać kod do tego ćwiczenia, sklonuj to repozytorium GitHub.

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

Jeśli nie masz zainstalowanego git, kliknij ten przycisk, aby uzyskać kod:

Aby można było jak najszybciej rozpocząć pracę, repozytorium zawiera kod startowy w folderze Starter. Jest on niezwykle przydatny w ćwiczeniach z programowania. Projekt startowy udostępnia podstawowy interfejs aplikacji i konfigurację kompilacji, ale nie ma dodanego pakietu Navigation SDK. Masz jeszcze ukończony projekt Solution, w którym możesz w dowolnej chwili przejść do kolejnego etapu lub sprawdzić swoje postępy.

Otwórz sklonowane repozytorium w Android Studio

Po sklonowaniu repozytorium lokalnie otwórz folder Starter jako istniejący projekt w Android Studio.

  1. W oknie Witamy w Android Studio kliknij przycisk Otwórz.
  2. Przejdź do folderu, w którym zapisano sklonowane repozytorium, i wybierz folder Starter w folderze najwyższego poziomu „codelab-navigation-101-android-kotlin”.
  3. Sprawdź, czy projekt się kompiluje i uruchamia.

Dodawanie urządzenia wirtualnego lub podłączanie urządzenia fizycznego

Aby połączyć urządzenie z Androidem z komputerami, postępuj zgodnie z instrukcjami dotyczącymi uruchamiania aplikacji na urządzeniu sprzętowym w Android Studio. Możesz też skonfigurować urządzenie wirtualne za pomocą Menedżera urządzenia wirtualnego z Androidem (AVD). Wybierając emulator, wybierz obraz, który zawiera interfejsy API Google.

W Android Studio kliknij opcję menu Uruchom lub ikonę przycisku odtwarzania. Wybierz urządzenie zgodnie z instrukcjami.

4. Dodawanie pakietu SDK nawigacji do aplikacji

Dodaj do projektu bibliotekę pakietu Navigation SDK i klucz interfejsu API

Aby dodać bibliotekę Navigation SDK do aplikacji, musisz zmodyfikować na poziomie aplikacji build.gradle.kts pakiet Navigation SDK, aby pobrać pakiet Navigation SDK z repozytorium Google Maven i skonfigurować numer wersji.

Utwórz w konfiguracji kompilacji zmienną do przechowywania numeru wersji pakietu Navigation SDK.

Skonfiguruj zmienną w build.gradle.kts na poziomie aplikacji, tak aby zawierała wartość wersji pakietu Navigation SDK używanej w aplikacji, aby w przyszłości można było z łatwością przejść na najnowszą wersję.

Numer najnowszej wersji znajdziesz w informacjach o wersji pakietu Navigation SDK.

val navSdkVersion by extra("6.0.0")

Wartości tej i innych zmiennych możesz też modyfikować w oknie dostępnym w menu Plik > Struktura projektu > Zmienne:

668332736b67dc82.png

Dodaj zależność do konfiguracji kompilacji

Teraz dodaj tę zależność interfejsu API do bloku zależności na poziomie aplikacji build.gradle.kts.Używana wersja będzie odpowiadać wartości parametru ${navSdkVersion}, który został właśnie ustawiony na poziomie aplikacji build.gradle.kts:

dependencies {

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

...

Dodawanie klucza interfejsu API

Zarządzanie kluczem interfejsu API za pomocą wtyczki Gradle obiektów tajnych

Zalecamy bezpieczne zarządzanie kluczem interfejsu API w aplikacji za pomocą wtyczki Gradle obiektów tajnych. Wtyczka została dodana do początkowego szablonu projektu jako zależność w pliku build.gradle.kts najwyższego poziomu.

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

Otwórz plik secrets.properties w katalogu najwyższego poziomu, a potem zastąp zmienną YOUR_API_KEY swoim kluczem API. Przechowuj klucz w tym pliku, ponieważ secrets.properties nie może zostać zaimportowany do systemu kontroli wersji.

MAPS_API_KEY=YOUR_API_KEY

Aby dowiedzieć się więcej na ten temat, zapoznaj się z sekcją Dodawanie klucza interfejsu API do aplikacji w dokumentacji pakietu Navigation SDK.

Sprawdź zawartość pliku local.defaults.properties

Pusty projekt zawiera też plik local.defaults.properties w katalogu najwyższego poziomu, czyli w tym samym folderze co plik secrets.properties. Otwórz go i zapoznaj się z poniższym kodem.

MAPS_API_KEY=DEFAULT_API_KEY

Służy ona do podawania wartości zapasowej dla właściwości MAPS_API_KEY na wypadek, gdyby do projektu nie dodano elementu secrets.properties, aby kompilacja się udała. Nie musisz edytować tego pliku. Jeśli nie uda się znaleźć definicji właściwości secrets.properties, wartość domyślna spowoduje zatrzymanie aplikacji w czasie jej działania z błędem klucza API.

Sprawdź, czy plik manifestu Androida używa podanego przez Ciebie klucza interfejsu API

Otwórz app/src/main/AndroidManifest.xml. Zauważ, że do ustawienia klucza API aplikacji służy właściwość MAPS_API_KEY:

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

Otwórz plik build.gradle.kts na poziomie aplikacji i znajdź właściwość secrets.

Ustawienie propertiesFileName w pliku plugin.xml powinno mieć wartość secrets.properties, a ustawienie defaultPropertiesFileName – wartość 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"
}

Zapisz wszystkie pliki i zsynchronizuj projekt z Gradle.

5. Konfigurowanie uprawnień aplikacji i dodawanie podstawowego interfejsu użytkownika

Proś o dostęp do dokładnej lokalizacji

Aby działać, pakiet SDK nawigacji wymaga sygnałów GPS, więc Twoja aplikacja będzie musiała poprosić użytkownika o przyznanie dostępu do dokładnych danych o lokalizacji. Dodaj uprawnienie dostępu do dokładnej lokalizacji jako element podrzędny elementu <manifest> w pliku 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>

Więcej informacji o uprawnieniach dostępu do lokalizacji w Androidzie znajdziesz w sekcji Prośba o uprawnienia dostępu do lokalizacji w dokumentacji dla deweloperów aplikacji na Androida.

Aby uruchomić aplikację na urządzeniu z Androidem 14, poproś o dostęp do lokalizacji usługi na pierwszym planie, dodając ten tag uses-permission w tej samej lokalizacji co uprawnienie dostępu do dokładnej lokalizacji:

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

Dodawanie działania związanego z uruchomieniem za pomocą podstawowego interfejsu

Gdy aplikacja zostanie uruchomiona, będzie potrzebował kodu, który jest wykonywany przy wstępie. Pozwala on sprawdzić, czy użytkownik przyznał dostęp do swojej lokalizacji, i zastosować każdy możliwy scenariusz, prosząc o przyznanie uprawnień, jeśli nie zostały jeszcze przyznane. Aby to zrobić, dodaj do aplikacji podstawowy interfejs użytkownika. Ten samouczek używa interfejsu, który jest tworzony podczas tworzenia nowej, pustej czynności Views w Android Studio. Dostosujesz je, aby sprawdzić dostęp do lokalizacji przed dodaniem kodu do aktywności w interfejsie nawigacji.

Otwórz plik MainActivity.kt w edytorze kodu i sprawdź kod, który przedstawia podstawowy interfejs użytkownika.

Wysyłanie prośby o dostęp do lokalizacji w czasie działania

Aplikacja musi wysłać prośbę o dostęp do dokładnej lokalizacji przed zainicjowaniem pakietu SDK nawigacji.

Aby mieć pewność, że sprawdzenie zostanie wykonane podczas uruchamiania aplikacji, dodaj kod do klasy MainActivity w przesłoniętej metodzie onCreate() aktywności.

Ten kod sprawdza, czy użytkownik przyznał dostęp do dokładnej lokalizacji. W przeciwnym razie poprosi o uprawnienia. Dodaj ten kod w metodzie 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

Dodaj do klasy MainActivity nową funkcję o nazwie onLocationPermissionGranted, która będzie obsługiwać wynik, gdy użytkownik udzieli uprawnień do udostępniania swojej lokalizacji. W następnych krokach dodamy tutaj kod uruchamiający nowe działanie związane z nawigacją.

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

Zbuduj projekt. Jeśli wystąpiły błędy kompilacji, znajdź je i napraw.

uruchomić projekt na nowym urządzeniu wirtualnym, Gdy aplikacja zostanie zainstalowana i uruchomiona, powinno pojawić się okno z prośbą o uprawnienia.

6. Dodaj interfejs nawigacyjny

Interfejs nawigacji można dodać na 2 sposoby: SupportNavigationFragment lub NavigationView.

Dla uproszczenia w tym laboratorium kodów używamy NavigationView.

Edytowanie układu

Edytuj res/layout/activity_main.xml, aby dodać układ do obiektu NavigationView.

  1. Otwórz plik i przełącz się na widok kodu.
  2. Zastąp całą zawartość pliku nowym układem NavigationView w ramach RelativeLayout, jak w przykładzie poniżej. Dodajesz do aplikacji widok nawigacji – wystarczy prosty układ.
  3. Nadaj widokowi nawigacji identyfikator „@+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>

Konfigurowanie aktywności związanej z nawigacją

W Android Studio otwórz plik MainActivity.kt w edytorze.

Dodaj podstawowy kod konfiguracji, aby zapewnić prawidłowe działanie nawigacji w aplikacji. W pliku MainActivity.kt wprowadź te zmiany:

  1. Zadeklaruj zmienną w klasie MainActivity, aby odwołać się do NavigationView:
private lateinit var navView: NavigationView
  1. Dodaj kod do metody onCreate(), aby uzyskać odniesienie do metody NavigationView:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
  1. Dodaj kod do metody onCreate(), aby mieć pewność, że ekran pozostanie włączony podczas korzystania ze wskazówek nawigacji:
// Ensure the screen stays on during nav.
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  1. Zmień kod wywołujący funkcję ViewCompat.setOnApplyWindowInsetsListener, aby odwoływać się do identyfikatora 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. Dodaj do klasy metodę showToast(), aby wyświetlić opinię użytkownika:
private fun showToast(errorMessage: String) {
   Toast.makeText(this@MainActivity, errorMessage, Toast.LENGTH_LONG).show()
}

7. Inicjowanie pakietu Navigation SDK

Po zakończeniu podstawowej konfiguracji nawigacji możesz zainicjować pakiet SDK nawigacji. Aby to zrobić, dodaj do pliku MainActivity.kt ten kod:

/** 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")
               }
           }
       },
   )

}

Ten kod tworzy nową metodę o nazwie initializeNavigationApi(). Ta metoda pobiera odwołanie do obiektu Navigator, wywołując NavigationApi.getNavigator(), i implementuje funkcję NavigatorListener, aby obsłużyć wywołanie zwrotne.

Zwróć uwagę, że po zainicjowaniu interfejsu Navigation API zostanie wywołana metoda NavigationListener.onNavigatorReady z przekazanym obiektem Navigator jako parametr. Powyższy kod zaktualizuje wcześniej zadeklarowaną zmienną mNavigator za pomocą zainicjowanego obiektu Navigator przekazanego do tej metody.

Na koniec dodaj wywołanie do metody initializeNavigationApi z metody onLocationPermissionGranted.

private fun onLocationPermissionGranted() {
   initializeNavigationApi()
}

8. Dodawanie odbiorców kluczowych zdarzeń nawigacji

Gdy użytkownicy postępują zgodnie z instrukcjami, pakiet Navigation SDK uruchamia zdarzenia, które mogą powiadomić aplikację o kluczowych zmianach stanu w trakcie podróży, np. gdy użytkownik zmieni trasę lub dotrze do miejsca docelowego. W pliku MainActivity.kt dodaj detektory do obsługi tych zdarzeń:

  1. W klasie MainActivity zadeklaruj 2 zmienne, aby odwołać się do obiektów detektora zdarzeń:
private var arrivalListener: Navigator.ArrivalListener? = null
private var routeChangedListener: Navigator.RouteChangedListener? = null
  1. Dodaj metodę registerNavigationListeners(), aby skonfigurować detektory po zainicjowaniu Navigator. Ta metoda wywołuje metodę Navigator.clearDestinations(), aby zresetować NavigationView po wywołaniu zdarzenia Przylot:
/**
* 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. Dodaj wywołanie do funkcji registerNavigationListeners() z kodu wywołania zwrotnego onNavigatorReady w metodzie initializeNavigationApi:
override fun onNavigatorReady(navigator: Navigator) {
   // store a reference to the Navigator object
   mNavigator = navigator

   //listen for events en route
   registerNavigationListeners()


}
  1. Skonfiguruj interfejs użytkownika. Podczas korzystania z nawigacji możesz kontrolować różne aspekty interfejsu nawigacji. Jedną z ważnych opcji dostosowywania jest pozycja kamery. Dodaj wywołanie metody setTaskRemovedBehaviour obiektu navigator zwracanego w funkcji onNavigatorReady w ten sposób: Spowoduje to wyłączenie wskazówek i powiadomień, gdy aplikacja zostanie przesunięta:
// 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. Aby określić CameraPerspective, dodaj do niego wywołanie GoogleMap.followMyLocation. Do elementu GoogleMap można uzyskać dostęp za pomocą metody NavigatorView.getMapAsync() w ten sposób:
navView.getMapAsync {
   googleMap  ->
   googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
  1. Aby zapewnić płynne działanie nawigacji przez cały cykl życia aplikacji, w klasie MainActivity zaimplementuj te metody:
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. Ustawianie miejsca docelowego

Możesz teraz ustawić miejsce docelowe i rozpocząć nawigację. W pliku MainActivity.kt wprowadź te zmiany:

  1. Dodaj nową metodę navigateToPlace(), która ustawia miejsce docelowe nawigacji i akceptuje parametr placeId.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {

}
  1. W metodzie navigateToPlace() użyj metody Waypoint.builder(), aby utworzyć element Waypoint na podstawie identyfikatora miejsca przekazanego do metody. Wykonaj obsługę żądania UnsupportedPlaceIdException, które może zgłosić w ten sposób, jeśli identyfikator miejsca nie wskazuje konkretnego adresu:
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. Dodaj następujący kod do metody navigateToPlace(), aby ustawić miejsce docelowe za pomocą 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")
   }
}

Obiekt Navigator zawiera metodę setDestinations(), która może przyjmować różne parametry. Najbardziej podstawową opcją jest podanie pola Waypoint. Domyślnie ustawiony zostanie tryb podróży DRIVING, odpowiedni dla samochodów osobowych. Metoda setDestinations() zwraca obiekt ListenableResultFuture zawierający obiekt RouteStatus. RouteStatus wskazuje, czy udało się znaleźć trasę do miejsca docelowego, a jeśli nie, umożliwia obsługę różnych stanów błędów.

  1. Aby poprawić wrażenia użytkowników korzystających z nawigacji, wprowadź dodatkowe zmiany w konfiguracji:
// 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)
   )
}

Wprowadzone zmiany obejmują następujące ulepszenia:

  • Ukrywam pasek działań, by zmaksymalizować przestrzeń na interfejs nawigacji.
  • Włączam wskazówki audio, aby głosowo podawać alerty i instrukcje nawigacji.
  • Skonfigurowanie symulatora do debugowania przez określenie mnożnika szybkości.
  1. Znajdź identyfikator miejsca, które będzie służyć jako miejsce docelowe. Najlepiej, żeby nie znajdowały się one zbyt daleko od lokalizacji użytkownika. Użyj narzędzia do wyszukiwania identyfikatorów miejsc w Google Maps Platform lub pobierz identyfikator miejsca z wywołania interfejsu Places API.

Jeśli symulujesz nawigację, możesz ustawić lokalizację użytkownika w kodzie lub pobrać ją z połączonego urządzenia. Codelab zakłada, że symulujesz lokalizację w Londynie w Wielkiej Brytanii.

  1. Dodaj obiekt towarzyszący do klasy MainActivity, aby przechowywać lokalizację początkową i identyfikator miejsca. Ćwiczenia z programowania korzystają z lokalizacji początkowej w Londynie oraz identyfikatora miejsca Trafalgar Square:
companion object{
   const val TRAFALGAR_SQUARE ="ChIJH-tBOc4EdkgRJ8aJ8P1CUxo" //London, UK
   val startLocation = LatLng(51.345678, -0.1234456)
}
  1. Dodaj wywołanie do metody navigateToPlace() z wywołania zwrotnego onNavigatorReady w metodzie initializeNavigationApi i dodaj gałąź logiczną, która będzie wykonywana w trybie debugowania, ustawiająca lokalizację użytkownika:
// 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. Tworzenie i uruchamianie kodu

Przy pierwszym uruchomieniu aplikacji musisz przyznać jej uprawnienia do lokalizacji i zaakceptować warunki korzystania z pakietu SDK nawigacji.

Uwaga: uruchomienie aplikacji spowoduje wywołanie metody setDestinations(), która powoduje naliczanie opłaty po pierwszym użyciu 1000 miejsc docelowych. Więcej informacji znajdziesz w artykule Korzystanie i rozliczenia.

93aa433000a14dfc.png

Okno z warunkami użytkowania Navigation SDK dla użytkownika końcowego.

Ustawianie lokalizacji

Domyślnie emulowane urządzenie może mieć ustawioną lokalizację Google kampusu w Mountain View w Kalifornii, chyba że ustawisz lokalizację w kodzie lub nie użyjesz okna właściwości emulatora.

W takim przypadku może się okazać, że aplikacja nie może znaleźć trasy do skonfigurowanego identyfikatora miejsca (domyślnie jest to Sydney Opera House, Sydney, Australia). W takim przypadku zobaczysz komunikat „Nie znaleziono trasy” wyświetlany przez metodę showToast().

Widok mapy aplikacji Nawigacja z biurem Google w Mountain View w Kalifornii.

Kodowanie lokalizacji początkowej

Aby ustawić inną lokalizację w kodzie, dodaj ten wiersz w metodzie navigateToPlace() w MainActivity.kt przed wywołaniem mNavigator.startGuidance():

mNavigator?.simulator?.setUserLocation(startLocation)

Uruchamianie emulatora w wybranej domyślnej lokalizacji

Aby ustawić inną lokalizację w dzienniku emulacji urządzenia, uruchom emulację, jeśli nie jest jeszcze uruchomiona, i kliknij menu z 3 kropkami z opisem „Rozszerzone opcje sterowania”. W wyświetlonym oknie znajduje się menu „Lokalizacja”.

Jeśli na przykład używasz identyfikatora miejsca Sydney Opera House jako miejsca docelowego, wybierz lokalizację w Sydney. Na przykład wyszukaj hasło „plaża Bondi”, wybierz sugestię i kliknij „Zapisz lokalizację”. w prawym dolnym rogu okna. Możesz też kliknąć „Zapisz punkt”. aby dodać lokalizację do zapisanej listy i użyć jej w przyszłości.

Okno z rozszerzonymi elementami sterującymi w Menedżerze urządzeń Android, przedstawiające selektor miejsc i mapę wyśrodkowaną na plaży Bondi w Australii.

Jeśli jako miejsce docelowe ustawisz inny identyfikator miejsca, wybierz lokalizację w pobliżu, aby symulowana trasa była realistyczna i niezbyt długa, co ułatwi debugowanie.

Uruchom ponownie aplikację, która powinna teraz doprowadzić Cię do miejsca docelowego.

Zrzut ekranu aplikacji Nawigacja pokazujący wskazówki do miejsca docelowego.

11. Gratulacje!

To ćwiczenie zostało ukończone. Super Ci poszło! Udało Ci się dotrzeć do celu! Miłego kodowania :-)

55812f33256c0596.png

12. Możesz zrobić jeszcze więcej

Jeśli chcesz rozwijać swoją aplikację, zapoznaj się z poniższymi tematami.