Za pomocą pakietu SDK Driver możesz usprawnić nawigację i śledzenie postępów w aplikacji Podróże i zamówienia. Pakiet Driver SDK zapewnia aktualne informacje o lokalizacji i zadaniach floty silnikówje i dostarcza rozwiązanie na żądanie.
SDK Driver sprawi, że usługi Fleet Engine i usługi niestandardowe będą znać lokalizację i stan pojazdu. Na przykład pojazd może mieć wartość ONLINE
lub OFFLINE
, a jego lokalizacja zmienia się w miarę postępów podróży.
Minimalne wymagania systemowe
Na urządzeniu mobilnym musi być zainstalowany Android 5.0 (poziom API 21) lub nowszy.
Wymagania wstępne
Pakiety SDK Transportu i Logistyki na Androida są publikowane w repozytorium Artifact Registry Maven. Repozytorium obejmuje pliki Project Object Model (.pom) pakietu SDK i pliki Java w trybie offline.
Uzyskaj dostęp
Jeśli korzystasz z Google Workspace, utwórz grupę Workspace, na przykład google-maps-platform-sdk-users@workspacedomain.com
, podczas rejestracji i podaj jej nazwę Google. Jest to zalecane.
Twoja grupa Workspace zostanie dodana do listy dozwolonych, która przyznaje dostęp do repozytorium Maven gmp-artifacts/transportation
.
Sprawdź, czy na liście znajdują się adresy e-mail użytkowników i konta usługi, które muszą mieć dostęp.
Jeśli Twoja organizacja nie może tworzyć grup Workspace, wyślij do Google listę adresów e-mail użytkowników i kont usługi, które potrzebują dostępu do tych artefaktów.
Programowanie lokalne
W przypadku programowania lokalnego wystarczy zalogować się za pomocą pakietu SDK Cloud.
gcloud
gcloud auth login
Adres e-mail używany do logowania musi należeć do grupy Workspace.
Automatyzacja (systemy kompilacji lub tryb ciągłej integracji)
Skonfiguruj hosty automatyzacji zgodnie ze sprawdzonymi metodami:
Jeśli proces działa w środowisku Google Cloud, skorzystaj z automatycznego wykrywania danych logowania.
W przeciwnym razie zapisz plik klucza konta usługi w bezpiecznej lokalizacji w systemie plików hosta i ustaw odpowiednio zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS.
Adres e-mail konta usługi powiązany z danymi logowania musi być członkiem grupy Workspace.
Konfiguracja
Skonfiguruj Maven lub Gradle, aby automatycznie wykrywać dane logowania użytkowników lub usług.
Gradle
Dodaj do pliku build.gradle
modułu aplikacji ten kod, a nie plik build.gradle
modułu głównego projektu:
plugins {
id "com.google.cloud.artifactregistry.gradle-plugin" version "2.1.5"
}
repositories {
maven {
url "artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation"
}
}
Maven
Dodaj do pom.xml
:
<repositories>
<repository>
<id>gmp-artifacts</id>
<url>artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.1.0</version>
</extension>
</extensions>
</build>
Więcej informacji o weryfikowaniu dostępu znajdziesz w artykule Zarządzanie pakietami Java.
Konfiguracja projektu
Aby korzystać z pakietu SDK Driver, Twoja aplikacja musi być kierowana na minSdkVersion
w wersji 21 lub nowszej.
Aby uruchomić aplikację stworzoną za pomocą pakietu SDK Driver, na urządzeniu z Androidem muszą być zainstalowane Usługi Google Play.
Konfigurowanie projektu programistycznego
Aby skonfigurować projekt deweloperski i uzyskać klucz interfejsu API dla projektu w Google Cloud Console:
Utwórz nowy projekt Google Cloud Console lub wybierz istniejący, który będzie używany z pakietem SDK Driver. Zaczekaj kilka minut, aż nowy projekt pojawi się w konsoli Google Cloud.
Aby uruchomić aplikację w wersji demonstracyjnej, Twój projekt musi mieć dostęp do pakietu SDK Maps na Androida. W konsoli Google Cloud wybierz Interfejsy API i usługi > Biblioteka, a potem wyszukaj i włącz pakiet SDK Map na Androida.
Aby uzyskać klucz interfejsu API projektu, wybierz Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz interfejsu API. Więcej informacji o uzyskiwaniu klucza interfejsu API znajdziesz w artykule Pobieranie klucza interfejsu API.
Dodaj do aplikacji pakiet SDK Driver
Pakiet SDK Driver jest dostępny w prywatnym repozytorium Maven. Repozytorium zawiera pliki Project Object Model (.pom) pakietu SDK i pliki Javadocs. Aby dodać pakiet SDK Driver do aplikacji:
- Skonfiguruj środowisko, aby uzyskać dostęp do repozytorium Maven w sposób opisany w sekcji Uzyskiwanie dostępu.
Dodaj zależność do konfiguracji Gradle lub Maven, zastępując zmienną
VERSION_NUMBER
odpowiednią wersją pakietu SDK sterownika.Gradle
Dodaj do
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER' }
Maven
Dodaj do
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-driver</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Dodawanie klucza interfejsu API do aplikacji
Po dodaniu pakietu SDK sterownika do aplikacji dodaj do niej klucz interfejsu API. Musisz użyć klucza interfejsu API projektu uzyskanego podczas konfigurowania projektu programistycznego.
W tej sekcji opisano, jak przechowywać klucz interfejsu API, tak by można było bezpieczniej odwoływać się do niego w aplikacji. Nie należy sprawdzać klucza interfejsu API w systemie kontroli wersji. Powinien być zapisany w pliku local.properties
, który znajduje się w katalogu głównym projektu. Więcej informacji o pliku local.properties
znajdziesz w artykule Pliki właściwości Gradle.
Aby uprościć to zadanie, możesz użyć wtyczki Gradle obiektów tajnych na Androida.
Aby zainstalować wtyczkę i zapisać klucz interfejsu API:
Otwórz plik
build.gradle
na poziomie katalogu głównego i dodaj ten kod do elementudependencies
w sekcjibuildscript
.Zakręcony
buildscript { dependencies { // ... classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0" } }
Kotlin
buildscript { dependencies { // ... classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0") } }
Otwórz plik
build.gradle
na poziomie aplikacji i dodaj do elementuplugins
ten kod.Zakręcony
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Jeśli używasz Android Studio, zsynchronizuj projekt z Gradle.
Otwórz
local.properties
w katalogu na poziomie projektu i dodaj ten kod. ZastąpYOUR_API_KEY
swoim kluczem interfejsu API.MAPS_API_KEY=YOUR_API_KEY
W pliku
AndroidManifest.xml
przejdź docom.google.android.geo.API_KEY
i zaktualizuj atrybutandroid:value
w następujący sposób:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
Poniższy przykład zawiera pełny plik manifestu przykładowej aplikacji:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.driverapidemo">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/_AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="${MAPS_API_KEY}" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Uwzględnij wymagane atrybucje w aplikacji
Jeśli używasz w aplikacji pakietu SDK Dysku Google, w sekcji informacji prawnych o aplikacji musisz uwzględnić tekst atrybucji i licencje open source. Atrybucja powinna znajdować się jako niezależna pozycja w menu lub jako część menu.
Wymagany tekst atrybucji i licencje open source znajdziesz w pliku ZIP z pakietem SDK Driver:
NOTICE.txt
LICENSES.txt
Zależności
Jeśli optymalizujesz kompilacje za pomocą ProGuard, może być konieczne dodanie do pliku konfiguracji ProGuard tych wierszy:
-dontwarn com.google.**
-dontwarn okio.**
Minimalny obsługiwany poziom interfejsu API to 21.
Inicjowanie pakietu SDK
Do zainicjowania obiektu DriverContext
wymagany jest identyfikator dostawcy (zwykle identyfikator projektu Google Cloud). Więcej informacji o konfigurowaniu projektu Google Cloud znajdziesz w artykule Uwierzytelnianie i autoryzacja.
Zanim zaczniesz korzystać z pakietu SDK Driver, musisz najpierw zainicjować pakiet SDK Nawigacji. Aby zainicjować pakiet SDK:
Uzyskaj obiekt
Navigator
zNavigationApi
.Java
NavigationApi.getNavigator( this, // Activity new NavigationApi.NavigatorListener() { @Override public void onNavigatorReady(Navigator navigator) { // Keep a reference to the Navigator (used to configure and start nav) this.navigator = navigator; } } );
Kotlin
NavigationApi.getNavigator( this, // Activity object : NavigatorListener() { override fun onNavigatorReady(navigator: Navigator) { // Keep a reference to the Navigator (used to configure and start nav) this@myActivity.navigator = navigator } }, )
Utwórz obiekt
DriverContext
, wypełniając wymagane pola.Java
DriverContext driverContext = DriverContext.builder(application) .setProviderId(providerId) .setVehicleId(vehicleId) .setAuthTokenFactory(authTokenFactory) .setNavigator(navigator) .setRoadSnappedLocationProvider( NavigationApi.getRoadSnappedLocationProvider(application)) .build();
Kotlin
val driverContext = DriverContext.builder(application) .setProviderId(providerId) .setVehicleId(vehicleId) .setAuthTokenFactory(authTokenFactory) .setNavigator(navigator) .setRoadSnappedLocationProvider(NavigationApi.getRoadSnappedLocationProvider(application)) .build()
Użyj obiektu
DriverContext
, aby zainicjować plik*DriverApi
.Java
RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
Kotlin
val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
Uzyskaj
RidesharingVehicleReporter
z obiektu API. (*VehicleReporter
obejmuje rozszerzenieNavigationVehicleReporter
).Java
RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
Kotlin
val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
Uwierzytelnianie w AuthTokenFactory
Gdy pakiet SDK kierowcy generuje aktualizacje lokalizacji, musi je wysyłać do serwera Fleet Engine. Aby uwierzytelnić te żądania, pakiet SDK kierowcy wywoła wywołanie API zawierające element wywołujący element AuthTokenFactory
.
Fabryka odpowiada za generowanie tokenów uwierzytelniania w czasie aktualizowania lokalizacji.
Sposób generowania tokenów zależy od sytuacji danego dewelopera. Wdrożenie prawdopodobnie będzie jednak wymagać:
- pobieranie tokena uwierzytelniania, prawdopodobnie w formacie JSON, z serwera HTTPS
- analiza i buforowanie tokena
- odśwież token po wygaśnięciu
Szczegółowe informacje o tokenach oczekiwanych przez serwer Fleet Engine znajdziesz w artykule Tworzenie tokena internetowego JSON (JWT) do autoryzacji.
Oto szkielet implementacji obiektu AuthTokenFactory
:
Java
class JsonAuthTokenFactory implements AuthTokenFactory {
private String token; // initially null
private long expiryTimeMs = 0;
// This method is called on a thread whose only responsibility is to send
// location updates. Blocking is OK, but just know that no location updates
// can occur until this method returns.
@Override
public String getToken(AuthTokenContext authTokenContext) {
if (System.currentTimeMillis() > expiryTimeMs) {
// The token has expired, go get a new one.
fetchNewToken(authTokenContext.getVehicleId());
}
return token;
}
private void fetchNewToken(String vehicleId) {
String url =
new Uri.Builder()
.scheme("https")
.authority("yourauthserver.example")
.appendPath("token")
.appendQueryParameter("vehicleId", vehicleId)
.build()
.toString();
try (Reader r = new InputStreamReader(new URL(url).openStream())) {
com.google.gson.JsonObject obj
= com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
token = obj.get("Token").getAsString();
expiryTimeMs = obj.get("TokenExpiryMs").getAsLong();
// The expiry time could be an hour from now, but just to try and avoid
// passing expired tokens, we subtract 10 minutes from that time.
expiryTimeMs -= 10 * 60 * 1000;
} catch (IOException e) {
// It's OK to throw exceptions here. The StatusListener you passed to
// create the DriverContext class will be notified and passed along the failed
// update warning.
throw new RuntimeException("Could not get auth token", e);
}
}
}
Kotlin
class JsonAuthTokenFactory : AuthTokenFactory() {
private var token: String = ""
private var expiryTimeMs: Long = 0
// This method is called on a thread whose only responsibility is to send
// location updates. Blocking is OK, but just know that no location updates
// can occur until this method returns.
override fun getToken(context: AuthTokenContext): String {
if (System.currentTimeMillis() > expiryTimeMs) {
// The token has expired, go get a new one.
fetchNewToken(authTokenContext.getVehicleId())
}
return token
}
fun fetchNewToken(vehicleId: String) {
val url =
Uri.Builder()
.scheme("https")
.authority("yourauthserver.example")
.appendPath("token")
.appendQueryParameter("vehicleId", vehicleId)
.build()
.toString()
try {
val reader = InputStreamReader(URL(url).openStream())
reader.use {
val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()
token = obj.get("ServiceToken").getAsString()
expiryTimeMs = obj.get("TokenExpiryMs").getAsLong()
// The expiry time could be an hour from now, but just to try and avoid
// passing expired tokens, we subtract 10 minutes from that time.
expiryTimeMs -= 10 * 60 * 1000
}
} catch (e: IOException) {
// It's OK to throw exceptions here. The StatusListener you passed to
// create the DriverContext class will be notified and passed along the failed
// update warning.
throw RuntimeException("Could not get auth token", e)
}
}
}
W tej konkretnej implementacji pobierany jest token w formacie JSON z wbudowanego klienta HTTP Java z serwera uwierzytelniania programisty. Token został zapisany do ponownego użycia. Token zostanie ponownie pobrany, jeśli do wygaśnięcia dojdzie w ciągu 10 minut.
Implementacja może wyglądać inaczej, na przykład użyć wątku w tle, aby odświeżyć tokeny.
Wyjątki w AuthTokenFactory
będą traktowane jako przejściowe, chyba że się to powtarzają. Po kilku próbach pakiet SDK kierowcy uzna, że błąd jest trwały, i przestanie wysyłać aktualizacje.
Raportowanie stanu i błędów w StatusListener
Ponieważ pakiet SDK sterownika wykonuje działania w tle, StatusListener
umożliwia wywoływanie powiadomień o wystąpieniach niektórych zdarzeń, takich jak błędy, ostrzeżenia czy komunikaty debugowania. Błędy mogą mieć charakter tymczasowy (np. BACKEND_CONNECTIVITY_ERROR
) albo powodować trwałe zatrzymywanie aktualizacji lokalizacji (np. VEHICLE_NOT_FOUND
, co wskazuje na błąd konfiguracji).
Opcjonujesz opcjonalną implementację StatusListener
w ten sposób:
Java
class MyStatusListener implements StatusListener {
/** Called when background status is updated, during actions such as location reporting. */
@Override
public void updateStatus(
StatusLevel statusLevel, StatusCode statusCode, String statusMsg) {
// Status handling stuff goes here.
// StatusLevel may be DEBUG, INFO, WARNING, or ERROR.
// StatusCode may be DEFAULT, UNKNOWN_ERROR, VEHICLE_NOT_FOUND,
// BACKEND_CONNECTIVITY_ERROR, or PERMISSION_DENIED.
}
}
Kotlin
class MyStatusListener : StatusListener() {
/** Called when background status is updated, during actions such as location reporting. */
override fun updateStatus(statusLevel: StatusLevel, statusCode: StatusCode, statusMsg: String) {
// Status handling stuff goes here.
// StatusLevel may be DEBUG, INFO, WARNING, or ERROR.
// StatusCode may be DEFAULT, UNKNOWN_ERROR, VEHICLE_NOT_FOUND,
// BACKEND_CONNECTIVITY_ERROR, or PERMISSION_DENIED.
}
}
Uwagi dotyczące SSL/TLS
Wewnętrzna implementacja pakietu Driver SDK używa SSL/TLS do bezpiecznej komunikacji z serwerem Fleet Engine. Starsze wersje Androida (interfejs API w wersji 19 lub starszej) mogą wymagać zainstalowania poprawki SecurityProvider
na potrzeby komunikacji z serwerem. Więcej informacji o korzystaniu z protokołu SSL w Androidzie znajdziesz w tym artykule. Artykuł zawiera też przykładowe fragmenty kodu do zastosowania poprawki dostawcy zabezpieczeń.
Włączam aktualizacje lokalizacji
Gdy masz instancję *VehicleReporter
, włączenie aktualizacji lokalizacji jest następujące:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
Kotlin
val reporter = ...
reporter.enableLocationTracking()
Informacje o lokalizacji są wysyłane w regularnych odstępach, gdy stan pojazdu to ONLINE
. Pamiętaj, że wywołanie reporter.enableLocationTracking()
nie ustawia automatycznie stanu pojazdu na ONLINE
. Musisz ustawić stan pojazdu.
Domyślnie interwał raportowania wynosi 10 sekund. Interwał raportowania można zmienić za pomocą reporter.setLocationReportingInterval(long, TimeUnit)
. Minimalny odstęp czasu aktualizacji wynosi 5 sekund. Częstsze aktualizacje mogą skutkować wolniejszymi żądaniami i błędami.
Wyłączanie aktualizacji lokalizacji
Po zakończeniu zmiany kierowcy można wyłączyć aktualizacje lokalizacji, a pojazd jest oznaczony jako offline przez wywołanie DeliveryVehicleReporter.disableLocationTracking
lub RidesharingVehicleReporter.disableLocationTracking
.
To wywołanie spowoduje zaplanowanie natychmiastowej ostatniej aktualizacji, która wskazuje, że pojazd jest offline. Ta aktualizacja nie będzie zawierać lokalizacji użytkownika.
Ustawianie stanu pojazdu
Po włączeniu aktualizacji lokalizacji ustawienie pojazdu na ONLINE
spowoduje udostępnienie pojazdu w zapytaniach SearchVehicles
. Analogicznie oznaczenie pojazdu jako OFFLINE
spowoduje oznaczenie go jako niedostępnego.
Stan pojazdu możesz ustawić po stronie serwera (patrz Aktualizacja pojazdu) lub bezpośrednio w pakiecie SDK kierowcy:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);
Kotlin
val reporter = ...
reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)
Gdy aktualizacje lokalizacji są włączone, przy następnej aktualizacji lokalizacji zostanie wywołane wywołanie setVehicleState
.
Jeśli nie włączysz śledzenia lokalizacji, oznaczenie pojazdu jako ONLINE
spowoduje IllegalStateException
. Jeśli nie masz włączonego lub wyraźnie wyłączonego śledzenia lokalizacji, pojazd może być oznaczony jako OFFLINE
. Spowoduje to natychmiastową aktualizację. Wywołanie RidesharingVehicleReporter.disableLocationTracking()
spowoduje ustawienie stanu pojazdu na OFFLINE
.
Zwróć uwagę, że wartość setVehicleState
zwraca się natychmiast, a aktualizacje są przeprowadzane w wątku aktualizacji lokalizacji. Podobnie jak w przypadku obsługi błędów w aktualizacjach lokalizacji błędy aktualizacji stanu pojazdu są rozpowszechniane za pomocą opcjonalnej wartości StatusListener
ustawionej w polu DriverContext
.