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.
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.
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.
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.
- W oknie Witamy w Android Studio kliknij przycisk Otwórz.
- Przejdź do folderu, w którym zapisano sklonowane repozytorium, i wybierz folder
Starter
w folderze najwyższego poziomu „codelab-navigation-101-android-kotlin
”. - 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:
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.
- Otwórz plik i przełącz się na widok kodu.
- Zastąp całą zawartość pliku nowym układem
NavigationView
w ramachRelativeLayout
, jak w przykładzie poniżej. Dodajesz do aplikacji widok nawigacji – wystarczy prosty układ. - 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:
- Zadeklaruj zmienną w klasie
MainActivity
, aby odwołać się doNavigationView
:
private lateinit var navView: NavigationView
- Dodaj kod do metody
onCreate()
, aby uzyskać odniesienie do metodyNavigationView
:
navView = findViewById(R.id.navigation_view)
navView.onCreate(savedInstanceState)
- 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)
- Zmień kod wywołujący funkcję
ViewCompat.setOnApplyWindowInsetsListener
, aby odwoływać się do identyfikatoraNavigationView
.
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
}
- 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ń:
- 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
- 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)
}
}
- Dodaj wywołanie do funkcji
registerNavigationListeners()
z kodu wywołania zwrotnegoonNavigatorReady
w metodzieinitializeNavigationApi
:
override fun onNavigatorReady(navigator: Navigator) {
// store a reference to the Navigator object
mNavigator = navigator
//listen for events en route
registerNavigationListeners()
}
- 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
obiektunavigator
zwracanego w funkcjionNavigatorReady
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)
- Aby określić
CameraPerspective
, dodaj do niego wywołanieGoogleMap.followMyLocation
. Do elementuGoogleMap
można uzyskać dostęp za pomocą metodyNavigatorView.getMapAsync()
w ten sposób:
navView.getMapAsync {
googleMap ->
googleMap.followMyLocation(GoogleMap.CameraPerspective.TILTED)
}
- 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:
- Dodaj nową metodę
navigateToPlace()
, która ustawia miejsce docelowe nawigacji i akceptuje parametrplaceId
.
/**
* Requests directions from the user's current location to a specific place (provided by the
* Place ID).
*/
private fun navigateToPlace(placeId: String) {
}
- W metodzie
navigateToPlace()
użyj metodyWaypoint.builder()
, aby utworzyć elementWaypoint
na podstawie identyfikatora miejsca przekazanego do metody. Wykonaj obsługę żądaniaUnsupportedPlaceIdException
, 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
}
- 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.
- 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.
- 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.
- 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)
}
- Dodaj wywołanie do metody
navigateToPlace()
z wywołania zwrotnegoonNavigatorReady
w metodzieinitializeNavigationApi
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.
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()
.
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.
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.
11. Gratulacje!
To ćwiczenie zostało ukończone. Super Ci poszło! Udało Ci się dotrzeć do celu! Miłego kodowania :-)
12. Możesz zrobić jeszcze więcej
Jeśli chcesz rozwijać swoją aplikację, zapoznaj się z poniższymi tematami.
- Nasłuchiwanie większej liczby zdarzeń nawigacji Dodaj kod, który wyświetli wiadomość, gdy kierowca zmieni trasę lub gdy dotrze na miejsce.
- Dostosuj interfejs nawigacji.
- Jeśli chcesz się zmierzyć z większym wyzwaniem, sprawdź, czy możesz dodać kontrolkę Place Picker interfejsu Places API, aby umożliwić użytkownikowi ustawienie miejsca docelowego. Wskazówka: aplikacje demonstracyjne Navigation SDK na GitHubie zawierają przykładową implementację.
- Aby uniknąć potencjalnych problemów z asyncjonalnym wywoływaniem obiektów Navigator i GoogleMap, zastosuj podejście stosowane w aplikacji demonstracyjnych Navigation SDK na Github. W bardziej złożonych scenariuszach dotyczących aplikacji te obiekty mogły nie zostać zakończone podczas uruchamiania kodu. Wskazówka: aby bardzo przyspieszyć implementację, możesz dodać klasę InitializedNavScope na końcu pliku MainActivity.kt.