Mit dem Driver SDK kannst du die Navigation und die Nachverfolgung deiner App für Fahrten und Bestellungen optimieren. Das Driver SDK stellt der Fleet Engine der On-demand Rides and Deliveries-Lösung Updates zu Fahrzeugstandorten und Aufgaben bereit.
Das Driver SDK hält die Fleet Engine-Dienste und Ihre benutzerdefinierten Dienste über den Standort und den Status des Fahrzeugs auf dem Laufenden. Das Fahrzeug kann beispielsweise ONLINE
oder OFFLINE
sein und der Standort des Fahrzeugs ändert sich im Laufe der Fahrt.
Mindestsystemanforderungen
Auf dem Mobilgerät muss Android 6.0 (API-Level 23) oder höher installiert sein.
Build- und Abhängigkeitenkonfiguration
Die Driver SDK-Version 4.99 und höher ist im Google Maven-Repository verfügbar.
Gradle
Füge deiner Datei build.gradle
Folgendes hinzu:
repositories {
...
google()
}
Maven
Füge deiner Datei pom.xml
Folgendes hinzu:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Projektkonfiguration
Wenn du das Driver SDK verwenden möchtest, muss deine App auf minSdkVersion
23 oder höher ausgerichtet sein.
Zum Ausführen einer App, die mit dem Driver SDK erstellt wurde, müssen auf dem Android-Gerät Google Play-Dienste installiert sein.
Entwicklungsprojekt einrichten
So richten Sie in der Google Cloud Console Ihr Entwicklungsprojekt ein und rufen einen API-Schlüssel für das Projekt ab:
Erstellen Sie ein neues Google Cloud Console-Projekt oder wählen Sie ein vorhandenes Projekt für die Verwendung mit dem Driver SDK aus. Warten Sie einige Minuten, bis das neue Projekt in der Google Cloud Console angezeigt wird.
Damit Sie die Demo-App ausführen können, muss Ihr Projekt Zugriff auf das Maps SDK for Android haben. Wählen Sie in der Google Cloud Console APIs und Dienste > Bibliothek aus, suchen Sie nach dem Maps SDK for Android und aktivieren Sie es.
Rufen Sie einen API-Schlüssel für das Projekt ab. Wählen Sie dazu APIs und Dienste > Anmeldedaten > Anmeldedaten erstellen > API-Schlüssel aus. Weitere Informationen
Treiber SDK zur App hinzufügen
Das Driver SDK ist im Google Maven-Repository verfügbar. Das Repository enthält die Project Object Model-Dateien (pom) des SDK und Javadocs. So fügen Sie Ihrer App das Driver SDK hinzu:
Fügen Sie Ihrer Gradle- oder Maven-Konfiguration die folgende Abhängigkeit hinzu und ersetzen Sie den Platzhalter
VERSION_NUMBER
durch die gewünschte Version des Driver SDK.Gradle
Fügen Sie zum
build.gradle
Folgendes hinzu:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER' }
Maven
Fügen Sie zum
pom.xml
Folgendes hinzu:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-driver</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Driver SDK hängt vom Navigation SDK ab. Diese Abhängigkeit ist so konfiguriert, dass eine bestimmte Version des Navigation SDK in der Build-Konfigurationsdatei explizit definiert werden muss, wie im Folgenden dargestellt. Durch Weglassen des Codeblocks kann das Projekt immer die neueste Version des Navigation SDK in der Hauptversion herunterladen. Das Verhalten der neuesten Versionen des Driver SDK und des Navigation SDK wurde vor den Veröffentlichungen gründlicher Tests durchgeführt.
Ordnen Sie die Abhängigkeitskonfiguration Ihrer Entwicklungs- und Release-Umgebungen entsprechend an.
Gradle
Fügen Sie zum
build.gradle
Folgendes hinzu:dependencies { ... implementation 'com.google.android.libraries.navigation:navigation:5.0.0' }
Maven
Fügen Sie zum
pom.xml
Folgendes hinzu:<dependencies> ... <dependency> <groupId>com.google.android.libraries.navigation</groupId> <artifactId>navigation</artifactId> <version>5.0.0</version> </dependency> </dependencies>
API-Schlüssel in die App einfügen
Fügen Sie Ihrer App den API-Schlüssel hinzu, nachdem Sie Ihrer App das Driver SDK hinzugefügt haben. Dazu müssen Sie den Projekt-API-Schlüssel verwenden, den Sie beim Einrichten Ihres Entwicklungsprojekts erhalten haben.
In diesem Abschnitt wird beschrieben, wie Sie Ihren API-Schlüssel speichern, damit er von Ihrer Anwendung sicherer referenziert werden kann. Er sollte nicht in Ihr Versionsverwaltungssystem eingecheckt werden. Sie sollte in der Datei local.properties
gespeichert werden, die sich im Stammverzeichnis Ihres Projekts befindet. Weitere Informationen zur Datei local.properties
finden Sie unter Gradle properties files (nur in englischer Sprache verfügbar).
Sie können das Secrets Gradle Plugin for Android verwenden, um diese Aufgabe zu optimieren.
So installieren Sie das Plug-in und speichern Ihren API-Schlüssel:
Öffnen Sie die Datei
build.gradle
auf Stammebene und fügen Sie folgenden Code in dasdependencies
-Element unterbuildscript
ein:Groovy
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") } }
Öffnen Sie die Datei
build.gradle
auf App-Ebene und fügen Sie den folgenden Code in dasplugins
-Element ein.Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Wenn Sie Android Studio verwenden, synchronisieren Sie Ihr Projekt mit Gradle.
Öffnen Sie die Datei
local.properties
in Ihrem Verzeichnis auf Projektebene und fügen Sie den folgenden Code hinzu. Ersetzen Sie dabeiYOUR_API_KEY
durch Ihren eigenen API-Schlüssel.MAPS_API_KEY=YOUR_API_KEY
Gehen Sie in der Datei
AndroidManifest.xml
zucom.google.android.geo.API_KEY
und aktualisieren Sie das Attributandroid:value
so:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
Das folgende Beispiel zeigt ein vollständiges Manifest für eine Beispiel-App:
<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>
Nimm die erforderlichen Quellenangaben in deine App auf.
Wenn Sie das Driver SDK in Ihrer App verwenden, müssen Sie im Abschnitt mit den rechtlichen Hinweisen der App Quellenangaben und Open-Source-Lizenzen angeben. Die Quellenangaben sollten am besten als eigenständigen Menüpunkt oder als Teil des Menüpunkts About (Info) eingefügt werden.
Die Lizenzinformationen finden Sie in der Datei „third_party_licenses.txt“ in der nicht archivierten AAR-Datei.
Weitere Informationen zum Einfügen von Open-Source-Hinweisen finden Sie unter https://developers.google.com/android/guides/opensource.
Abhängigkeiten
Wenn Sie Ihre Builds mit ProGuard optimieren, müssen Sie der ProGuard-Konfigurationsdatei möglicherweise die folgenden Zeilen hinzufügen:
-dontwarn com.google.**
-dontwarn okio.**
Das mindestens unterstützte API-Level ist 23.
SDK initialisieren
Zum Initialisieren des DriverContext
-Objekts ist eine Anbieter-ID (in der Regel die Google Cloud-Projekt-ID) erforderlich. Weitere Informationen zum Einrichten des Google Cloud-Projekts finden Sie unter Authentifizierung und Autorisierung.
Bevor Sie das Driver SDK verwenden können, müssen Sie zuerst das Navigation SDK initialisieren. So initialisieren Sie das SDK:
Ruft ein
Navigator
-Objekt aus demNavigationApi
ab.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 } }, )
Erstellen Sie ein
DriverContext
-Objekt und füllen Sie die Pflichtfelder aus.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()
Verwenden Sie das Objekt
DriverContext
, um*DriverApi
zu initialisieren.Java
RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
Kotlin
val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
Rufen Sie die
RidesharingVehicleReporter
aus dem API-Objekt ab. (*VehicleReporter
erweitertNavigationVehicleReporter
.)Java
RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
Kotlin
val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
Authentifizierung bei AuthTokenFactory
Wenn das Driver SDK Standortaktualisierungen generiert, müssen diese an den Fleet Engine-Server gesendet werden. Um diese Anfragen zu authentifizieren, sendet das Driver SDK eine vom Aufrufer bereitgestellte Instanz von AuthTokenFactory
an.
Die Factory ist für das Generieren von Authentifizierungstokens zum Zeitpunkt der Standortaktualisierung verantwortlich.
Wie genau Tokens generiert werden, hängt von der Situation des jeweiligen Entwicklers ab. Für die Implementierung ist wahrscheinlich jedoch Folgendes erforderlich:
- ein Authentifizierungstoken, möglicherweise im JSON-Format, von einem HTTPS-Server abrufen
- Token parsen und im Cache speichern
- das Token nach Ablauf aktualisieren
Weitere Informationen zu den vom Fleet Engine-Server erwarteten Tokens finden Sie unter JSON Web Token (JWT) für die Autorisierung erstellen.
Hier ist eine grundlegende Implementierung eines 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)
}
}
}
Bei dieser speziellen Implementierung wird der integrierte Java-HTTP-Client verwendet, um ein Token im JSON-Format vom Authentifizierungsserver des Entwicklers abzurufen. Das Token wird zur Wiederverwendung gespeichert. Das Token wird noch einmal abgerufen, wenn sich das alte Token innerhalb von 10 Minuten nach seiner Ablaufzeit befindet.
Ihre Implementierung kann anders vorgehen, z. B. die Verwendung eines Hintergrundthreads zum Aktualisieren von Tokens.
Ausnahmen in AuthTokenFactory
werden als vorübergehend behandelt, sofern sie nicht wiederholt auftreten. Nach mehreren Versuchen geht das Driver SDK davon aus, dass der Fehler dauerhaft ist, und es werden keine Updates mehr gesendet.
Status- und Error Reporting mit StatusListener
Da das Driver SDK Aktionen im Hintergrund ausführt, verwenden Sie StatusListener
, um bei bestimmten Ereignissen Benachrichtigungen auszulösen, z. B. Fehler, Warnungen oder Debug-Meldungen. Fehler können vorübergehend sein (z. B. BACKEND_CONNECTIVITY_ERROR
) oder dazu führen, dass Standortaktualisierungen dauerhaft gestoppt werden (z. B. VEHICLE_NOT_FOUND
, was einen Konfigurationsfehler anzeigt).
Du stellst eine optionale StatusListener
-Implementierung wie die folgende bereit:
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.
}
}
Hinweise zu SSL/TLS
Intern verwendet die Driver SDK-Implementierung SSL/TLS, um sicher mit dem Fleet Engine-Server zu kommunizieren. Für ältere Android-Versionen (API-Version 19 oder niedriger) ist möglicherweise ein SecurityProvider
-Patch erforderlich, um mit dem Server kommunizieren zu können. Weitere Informationen zur Arbeit mit SSL unter Android finden Sie in diesem Artikel. Der Artikel enthält auch Codebeispiele zum Patchen des Sicherheitsanbieters.
Standortaktualisierungen aktivieren
Sobald Sie eine *VehicleReporter
-Instanz haben, ist das Aktivieren von Standortupdates ganz einfach:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
Kotlin
val reporter = ...
reporter.enableLocationTracking()
Standortaktualisierungen werden in regelmäßigen Abständen gesendet, wenn der Fahrzeugstatus ONLINE
ist. Durch das Aufrufen von reporter.enableLocationTracking()
wird der Fahrzeugstatus nicht automatisch auf ONLINE
gesetzt. Sie müssen den Fahrzeugstatus explizit festlegen.
Standardmäßig beträgt das Intervall für die Berichterstellung 10 Sekunden. Das Berichtsintervall kann mit reporter.setLocationReportingInterval(long, TimeUnit)
geändert werden. Das unterstützte Mindestintervall für Updates beträgt 5 Sekunden. Häufigere Aktualisierungen können zu langsameren Anfragen und Fehlern führen.
Standortaktualisierungen deaktivieren
Wenn die Schicht beendet ist, können Standortaktualisierungen angehalten und das Fahrzeug durch Aufrufen von DeliveryVehicleReporter.disableLocationTracking
oder RidesharingVehicleReporter.disableLocationTracking
als offline markiert werden.
Durch diesen Aufruf wird ein letztes Update für die sofortige Lieferung geplant. Dieses gibt an, dass das Fahrzeug offline ist. Der Standort des Nutzers wird in dieser Aktualisierung nicht aufgeführt.
Fahrzeugstatus wird festgelegt
Wenn Standortaktualisierungen aktiviert sind, wird das Fahrzeug durch Festlegen des Fahrzeugstatus auf ONLINE
für SearchVehicles
-Abfragen verfügbar gemacht. Wenn ein Fahrzeug als OFFLINE
gekennzeichnet wird, wird es ebenfalls als nicht verfügbar gekennzeichnet.
Sie können den Fahrzeugstatus serverseitig (siehe Fahrzeug aktualisieren) oder direkt im Driver SDK festlegen:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);
Kotlin
val reporter = ...
reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)
Wenn Standortaktualisierungen aktiviert sind, wird ein Aufruf von setVehicleState
beim nächsten Standortupdate weitergegeben.
Wenn ein Fahrzeug als ONLINE
markiert wird, obwohl die Standortermittlung nicht aktiviert ist, wird ein IllegalStateException
ausgegeben. Ein Fahrzeug kann als OFFLINE
gekennzeichnet werden, wenn die Standortermittlung noch nicht aktiviert oder explizit deaktiviert ist. Dies führt zu einer sofortigen Aktualisierung. Durch einen Aufruf von RidesharingVehicleReporter.disableLocationTracking()
wird der Fahrzeugstatus auf OFFLINE
gesetzt.
setVehicleState
wird sofort zurückgegeben und Aktualisierungen werden im Thread zur Standortaktualisierung durchgeführt. Ähnlich wie bei der Fehlerbehandlung bei Standortaktualisierungen werden Fehler bei der Aktualisierung des Fahrzeugstatus über den optional bereitgestellten StatusListener
, der in der DriverContext
festgelegt ist, weitergegeben.