Puoi utilizzare l'SDK Driver per fornire funzionalità di navigazione e monitoraggio avanzate alla tua richiesta di avanzamento dei viaggi e degli ordini. L'SDK Driver fornisce aggiornamenti sulla posizione dei veicoli e sulle attività per il motore On-demand Rides and Deliveries Solution Fleet Engine.
L'SDK Driver tiene al corrente i servizi Fleet Engine e i tuoi servizi personalizzati
della posizione e dello stato del veicolo. Ad esempio, il veicolo può essere ONLINE
o OFFLINE
e la posizione del veicolo cambia man mano che la corsa prosegue.
Requisiti minimi di sistema
Sul dispositivo mobile deve essere installato Android 6.0 (livello API 23) o versioni successive.
Configurazione della build e delle dipendenze
Le versioni dell'SDK driver 4.99 e successive sono disponibili nel Repository Maven di Google.
Gradle
Aggiungi quanto segue al tuo file build.gradle
:
repositories {
...
google()
}
Maven
Aggiungi quanto segue al tuo file pom.xml
:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Configurazione progetto
Per utilizzare l'SDK Driver, la tua app deve avere come target
minSdkVersion
23 o superiore.
Per eseguire un'app creata con l'SDK Driver, l'applicazione il dispositivo deve avere Google Play Services installato.
Configura il progetto di sviluppo
Per configurare il progetto di sviluppo e ottenere una chiave API: per il progetto nella console Google Cloud:
Crea un nuovo progetto nella console Google Cloud o selezionane uno esistente da utilizzare con l'SDK Driver. Attendi qualche minuto il nuovo progetto sia visibile nella console Google Cloud.
Per eseguire l'app demo, il progetto deve avere accesso a Maps SDK per Android. Nella console Google Cloud, seleziona API e Servizi > Library, quindi cerca e attiva Maps SDK per Android.
Ottieni una chiave API per il progetto selezionando API e Servizi > Credenziali > Crea le credenziali > chiave API. Per ulteriori informazioni su come ottenere una chiave API, consulta Ottieni una chiave API.
Aggiungi l'SDK Driver alla tua app
L'SDK Driver è disponibile nel Repository Maven di Google. La Il repository include i file Project Object Model (.pom) e Javadocs dell'SDK. Per aggiungere l'SDK Driver alla tua app:
Aggiungi la seguente dipendenza alla configurazione Gradle o Maven, sostituendo il segnaposto Segnaposto
VERSION_NUMBER
per la versione desiderata dell'SDK driver.Gradle
Aggiungi il seguente codice a
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER' }
Maven
Aggiungi il seguente codice a
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-driver</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
L'SDK Driver dipende dall'SDK di navigazione e questa dipendenza è configurata in un in modo che, se è necessaria una versione specifica dell'SDK di navigazione, esplicitamente definito nel file di configurazione della build, come riportato di seguito, ometti il blocco di codice menzionato, il progetto potrà sempre scaricare all'ultima versione dell'SDK di navigazione all'interno della versione di release principale. Tieni presente che i comportamenti combinati delle ultime versioni dell'SDK Driver e L'SDK di navigazione è stato sottoposto a test rigorosi prima delle release.
Organizza la configurazione delle dipendenze per lo sviluppo e la release ambienti di lavoro di conseguenza.
Gradle
Aggiungi il seguente codice a
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.navigation:navigation:5.0.0' }
Maven
Aggiungi il seguente codice a
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.navigation</groupId> <artifactId>navigation</artifactId> <version>5.0.0</version> </dependency> </dependencies>
Aggiungi la chiave API all'app
Dopo aver aggiunto l'SDK Driver all'app, aggiungi la chiave API all'app. Tu devi usare la chiave API del progetto che hai ottenuto configurare il progetto di sviluppo.
Questa sezione descrive come archiviare la chiave API in modo che possa essere
a cui fa riferimento la tua app. Non controllare la tua versione con la chiave API
di controllo dei dati. Dovrebbe essere archiviato nel file local.properties
, che è
nella directory radice del progetto. Per ulteriori informazioni
local.properties
file, vedi
File delle proprietà di Gradle.
Per semplificare questa attività, puoi utilizzare plug-in Secrets Gradle per Android.
Per installare il plug-in e memorizzare la chiave API:
Apri il file
build.gradle
a livello di directory principale e aggiungi il seguente codice alla Elementodependencies
inbuildscript
.Trendy
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") } }
Apri il file
build.gradle
a livello di app e aggiungi il seguente codice alla Elementoplugins
.Trendy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Se usi Android Studio, sincronizzare il progetto con Gradle.
Apri
local.properties
nella directory a livello di progetto, quindi aggiungi seguire il codice. SostituisciYOUR_API_KEY
con la tua chiave API.MAPS_API_KEY=YOUR_API_KEY
Nel file
AndroidManifest.xml
, vai acom.google.android.geo.API_KEY
e aggiorna l'attributoandroid:value
come segue:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
L'esempio seguente mostra un manifest completo per un'app di esempio:
<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>
Includi le attribuzioni richieste nella tua app
Se utilizzi l'SDK Driver nella tua app, devi includere testo di attribuzione e licenze open source nell'ambito delle note legali dell'app . È meglio includere le attribuzioni come voce di menu indipendente o come di una voce di menu Informazioni.
Le informazioni sulle licenze sono disponibili nel file "third_party_licenses.txt" file in del file AAR non archiviato.
Visita la pagina https://developers.google.com/android/guides/opensource su come includere avvisi open source.
Dipendenze
Se utilizzi ProGuard per ottimizzare le build, potresti dover aggiungere le seguenti righe a ProGuard di configurazione del deployment:
-dontwarn com.google.**
-dontwarn okio.**
Il livello API minimo supportato è 23.
Inizializzazione dell'SDK
Per
inizializza l'oggetto DriverContext
. Per ulteriori dettagli sulla configurazione
progetto Google Cloud, consulta
Autenticazione e autorizzazione.
Prima di utilizzare l'SDK driver, devi inizializzare l'SDK di navigazione. Per inizializzare l'SDK:
Ottieni un oggetto
Navigator
daNavigationApi
.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 } }, )
Crea un oggetto
DriverContext
e compila i campi obbligatori.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()
Utilizza l'oggetto
DriverContext
per inizializzare*DriverApi
.Java
RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
Kotlin
val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
Ottieni
RidesharingVehicleReporter
dall'oggetto API. (*VehicleReporter
estendeNavigationVehicleReporter
.)Java
RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
Kotlin
val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
Autenticazione con AuthTokenFactory
Quando l'SDK Driver genera aggiornamenti della posizione,
deve inviare questi aggiornamenti
il server Fleet Engine. Per autenticare queste richieste,
L'SDK del driver chiamerà un utente fornito dal chiamante
di AuthTokenFactory
.
La fabbrica è responsabile della generazione dei token di autenticazione presso la sede
aggiornare l'ora.
La modalità di generazione dei token sarà specifica per la situazione di ogni sviluppatore. Tuttavia, l'implementazione dovrà probabilmente:
- Recuperare un token di autenticazione, possibilmente in formato JSON, da un server HTTPS
- analizza e memorizza nella cache il token
- aggiorna il token alla scadenza
Per maggiori dettagli sui token previsti dal server Fleet Engine, consulta Creazione di un token JWT (JSON Web Token) per l'autorizzazione.
Ecco uno schema di implementazione di un 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)
}
}
}
Questa particolare implementazione utilizza il client HTTP Java integrato per recuperare un in formato JSON dal server di autenticazione dello sviluppatore. Il token è salvate per essere riutilizzate. Il token viene recuperato se il vecchio token rientra tra 10 minuti dalla data di scadenza.
La tua implementazione potrebbe fare le cose in modo diverso, ad esempio utilizzare un thread in background per aggiornare i token.
Le eccezioni in AuthTokenFactory
verranno trattate come temporanee, a meno che non si verifichino
ripetutamente. Dopo una serie di tentativi, l'SDK Driver
supporremo che
l'errore è permanente e smetterà di provare a inviare aggiornamenti.
Segnalazione di stato ed errori con StatusListener
Poiché l'SDK dei driver esegue azioni
in background, usa StatusListener
per attivare notifiche quando
al verificarsi di determinati eventi, ad esempio errori, avvisi o messaggi di debug. Gli errori potrebbero essere
di natura temporanea (ad esempio BACKEND_CONNECTIVITY_ERROR
) oppure potrebbero
causano l'interruzione definitiva degli aggiornamenti della posizione (ad esempio VEHICLE_NOT_FOUND
,
che indica un errore di configurazione).
Fornisci un'implementazione facoltativa di tipo StatusListener
, come la seguente:
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.
}
}
Note su SSL/TLS
Internamente, l'implementazione dell'SDK del driver utilizza
SSL/TLS per comunicare in modo sicuro
con il server Fleet Engine. Versioni precedenti di Android (versioni API 19 o
inferiore) potrebbe richiedere una patch SecurityProvider
per comunicare
o server web. Dovresti vedere questo
articolo
per ulteriori informazioni sull'uso di SSL in Android. L'articolo include inoltre
contiene esempi di codice per l'applicazione di patch al provider di sicurezza.
Attivazione aggiornamenti posizione
Una volta ottenuta un'istanza *VehicleReporter
, l'abilitazione degli aggiornamenti della posizione
semplice:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
Kotlin
val reporter = ...
reporter.enableLocationTracking()
Gli aggiornamenti sulla posizione vengono inviati a intervalli regolari quando lo stato del veicolo è
ONLINE
. Tieni presente che la chiamata al numero reporter.enableLocationTracking()
non
imposta automaticamente lo stato del veicolo su ONLINE
. Devi
impostare lo stato del veicolo in modo esplicito.
Per impostazione predefinita, l'intervallo del report è di 10 secondi. L'intervallo di report può
da modificare con reporter.setLocationReportingInterval(long, TimeUnit)
. La
l'intervallo di aggiornamento minimo supportato è di 5 secondi. Aggiornamenti più frequenti possono
il che comporta richieste ed errori più lenti.
Disattivazione degli aggiornamenti della posizione in corso...
Quando il turno del conducente è terminato, gli aggiornamenti della posizione possono essere interrotti
veicolo contrassegnato offline tramite chiamata
DeliveryVehicleReporter.disableLocationTracking
o
RidesharingVehicleReporter.disableLocationTracking
.
Con questa chiamata verrà pianificato un aggiornamento finale per l'invio immediato, che indica che il veicolo è offline. Questo aggiornamento non conterrà i dati dell'utente in ogni località.
Impostazione dello stato del veicolo
Quando gli aggiornamenti della posizione sono attivi, l'impostazione dello stato del veicolo su ONLINE
rendi il veicolo disponibile per SearchVehicles
query; allo stesso modo, contrassegnando
il veicolo come OFFLINE
lo contrassegnerà come non disponibile.
Puoi impostare lo stato del veicolo sul lato server (vedi Aggiornare un veicolo), oppure direttamente nell'SDK driver:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);
Kotlin
val reporter = ...
reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)
Quando gli aggiornamenti della posizione sono abilitati, la chiamata a setVehicleState
verrà propagata alle
al prossimo aggiornamento della posizione.
Se contrassegni un veicolo come ONLINE
quando il monitoraggio della posizione non è abilitato,
in un IllegalStateException
. Un veicolo può essere contrassegnato come OFFLINE
quando
il monitoraggio della posizione non è ancora attivato o esplicitamente disattivato. Questo comporterà
in un aggiornamento immediato. Una chiamata a
Azione che RidesharingVehicleReporter.disableLocationTracking()
eseguirà
imposta lo stato del veicolo su OFFLINE
.
Tieni presente che setVehicleState
torna immediatamente e gli aggiornamenti vengono eseguiti nella
thread di aggiornamento della posizione. Analogamente alla gestione degli errori
degli aggiornamenti delle sedi, gli errori
aggiornamento dello stato del veicolo vengono propagati utilizzando
Valore StatusListener
impostato in DriverContext
.