Vous pouvez utiliser le SDK Driver pour améliorer la navigation et le suivi dans votre application "Trajet et progression de la commande". Le SDK Driver fournit des informations sur l'emplacement des véhicules et les tâches au moteur du parc de solutions On-demand Rides and Deliveries.
Le SDK Driver informe les services Fleet Engine et vos services personnalisés de l'emplacement et de l'état du véhicule. Par exemple, le véhicule peut être ONLINE
ou OFFLINE
, et son emplacement change au fur et à mesure du trajet.
Configuration système minimale requise
L'appareil mobile doit être équipé d'Android 5.0 (niveau d'API 21) ou version ultérieure.
Configuration Maven
Les versions 4.99 et ultérieures du SDK sont disponibles via le dépôt Maven de Google.
Gradle
Ajoutez le code ci-dessous à votre fichier build.gradle
:
repositories {
...
google()
}
Maven
Ajoutez le code ci-dessous à votre fichier pom.xml
:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Configuration du projet
Pour utiliser le SDK Driver, votre application doit cibler minSdkVersion
21 ou une version ultérieure.
Pour exécuter une application créée avec le SDK Driver, les services Google Play doivent être installés sur l'appareil Android.
Configurer votre projet de développement
Pour configurer votre projet de développement et obtenir une clé API pour le projet dans la console Google Cloud:
Créez un projet dans la console Google Cloud ou sélectionnez un projet existant à utiliser avec le SDK Driver. Attendez quelques minutes que le nouveau projet soit visible dans la console Google Cloud.
Pour que vous puissiez exécuter l'application de démonstration, votre projet doit avoir accès au SDK Maps pour Android. Dans la console Google Cloud, sélectionnez API et services > Bibliothèque, puis recherchez et activez le SDK Maps pour Android.
Obtenez une clé API pour le projet en sélectionnant API et services > Identifiants > Créer des identifiants > Clé API. Pour savoir comment obtenir une clé API, consultez Obtenir une clé API.
Ajouter le SDK Driver à votre application
Le SDK Driver est disponible via un dépôt Maven privé. Le dépôt comprend les fichiers de modèle d'objet de projet (.pom) et les Javadocs du SDK. Pour ajouter le SDK Driver à votre application:
Ajoutez la dépendance suivante à votre configuration Gradle ou Maven, en remplaçant l'espace réservé
VERSION_NUMBER
par la version souhaitée du SDK pilote.Gradle
Ajoutez les éléments suivants à votre
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:VERSION_NUMBER' }
Maven
Ajoutez les éléments suivants à votre
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-driver</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Ajouter la clé API à votre application
Une fois que vous avez ajouté le SDK Driver à votre application, ajoutez la clé API à votre application. Vous devez utiliser la clé API du projet que vous avez obtenue lors de la configuration de votre projet de développement.
Cette section explique comment stocker votre clé API afin que votre application puisse la référencer de manière plus sécurisée. Vous ne devez pas vérifier votre clé API dans votre système de contrôle des versions. Il doit être stocké dans le fichier local.properties
, qui se trouve dans le répertoire racine de votre projet. Pour en savoir plus sur le fichier local.properties
, consultez Fichiers de propriétés Gradle.
Pour vous faciliter la tâche, vous pouvez utiliser le plug-in Secrets Gradle pour Android.
Pour installer le plug-in et stocker votre clé API :
Ouvrez votre fichier
build.gradle
au niveau racine et ajoutez le code suivant à l'élémentdependencies
sousbuildscript
.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") } }
Ouvrez le fichier
build.gradle
au niveau de l'application et ajoutez le code suivant à l'élémentplugins
.Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Si vous utilisez Android Studio, synchronisez votre projet avec Gradle.
Ouvrez
local.properties
dans votre répertoire au niveau du projet, puis ajoutez le code suivant. RemplacezYOUR_API_KEY
par votre clé API.MAPS_API_KEY=YOUR_API_KEY
Dans votre fichier
AndroidManifest.xml
, accédez àcom.google.android.geo.API_KEY
et mettez à jour l'attributandroid:value
comme suit:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
L'exemple suivant présente un fichier manifeste complet pour une application exemple:
<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>
Inclure les attributions requises dans votre application
Si vous utilisez le SDK Driver dans votre application, vous devez inclure un texte d'attribution et des licences Open Source dans la section des mentions légales de votre application. Il est préférable d'inclure les attributions dans un élément de menu indépendant ou dans un élément de menu About (À propos).
Vous trouverez le texte d'attribution et les licences Open Source requis dans le fichier ZIP du SDK Driver:
NOTICE.txt
LICENSES.txt
Dépendances
Si vous utilisez ProGuard pour optimiser vos compilations, vous devrez peut-être ajouter les lignes suivantes à votre fichier de configuration ProGuard:
-dontwarn com.google.**
-dontwarn okio.**
Le niveau d'API minimal accepté est 21.
Initialiser le SDK
Un ID de fournisseur (généralement l'ID de projet Google Cloud) est nécessaire pour initialiser l'objet DriverContext
. Pour en savoir plus sur la configuration du projet Google Cloud, consultez la page Authentification et autorisation.
Avant d'utiliser le SDK Driver, vous devez d'abord initialiser le SDK Navigation. Pour initialiser le SDK, procédez comme suit :
Obtenez un objet
Navigator
à partir deNavigationApi
.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 } }, )
Créez un objet
DriverContext
en remplissant les champs obligatoires.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()
Utilisez l'objet
DriverContext
pour initialiser*DriverApi
.Java
RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
Kotlin
val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
Récupérez
RidesharingVehicleReporter
à partir de l'objet API. (*VehicleReporter
étendNavigationVehicleReporter
.)Java
RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
Kotlin
val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
Authentification avec AuthTokenFactory
Lorsque le SDK Driver génère des mises à jour de position, il doit les envoyer au serveur Fleet Engine. Pour authentifier ces requêtes, le SDK Driver appelle une instance de AuthTokenFactory
fournie par l'appelant.
La fabrique est chargée de générer les jetons d'authentification au moment de la mise à jour de l'établissement.
La façon dont les jetons sont générés dépend de la situation de chaque développeur. Toutefois, vous devrez probablement procéder comme suit pour l'implémentation:
- Récupérer un jeton d'authentification, éventuellement au format JSON, à partir d'un serveur HTTPS
- analyser et mettre en cache le jeton
- Actualiser le jeton lorsqu'il expire
Pour en savoir plus sur les jetons attendus par le serveur Fleet Engine, consultez la page Créer un jeton Web JSON (JWT) pour l'autorisation.
Voici un squelette d'implémentation d'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)
}
}
}
Cette implémentation utilise le client HTTP Java intégré pour extraire un jeton au format JSON à partir du serveur d'authentification du développeur. Le jeton est enregistré pour être réutilisé. Le jeton est à nouveau récupéré si l'ancien jeton se trouve à moins de 10 minutes de son délai d'expiration.
Votre implémentation peut agir différemment, par exemple utiliser un thread d'arrière-plan pour actualiser les jetons.
Les exceptions dans AuthTokenFactory
seront traitées comme temporaires, sauf si elles se produisent à plusieurs reprises. Après plusieurs tentatives, le SDK Driver suppose que l'erreur est permanente et cessera d'essayer d'envoyer des mises à jour.
Rapport d'état et d'erreur avec StatusListener
Étant donné que le SDK Driver effectue des actions en arrière-plan, utilisez StatusListener
pour déclencher des notifications lorsque certains événements se produisent, tels que des erreurs, des avertissements ou des messages de débogage. Les erreurs peuvent être temporaires (par exemple, BACKEND_CONNECTIVITY_ERROR
) ou entraîner l'arrêt permanent des mises à jour de la position (par exemple, VEHICLE_NOT_FOUND
, qui indique une erreur de configuration).
Vous fournissez une implémentation StatusListener
facultative, comme suit:
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.
}
}
Remarques sur SSL/TLS
En interne, la mise en œuvre du SDK pilote utilise SSL/TLS pour communiquer de manière sécurisée avec le serveur Fleet Engine. Les anciennes versions d'Android (API 19 ou antérieures) peuvent nécessiter un correctif SecurityProvider
pour pouvoir communiquer avec le serveur. Consultez cet article pour en savoir plus sur l'utilisation de SSL dans Android. Il contient également des exemples de code permettant d'appliquer des correctifs au fournisseur de sécurité.
Activer les mises à jour de la position géographique
Une fois que vous disposez d'une instance *VehicleReporter
, l'activation des mises à jour de la position est simple:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
Kotlin
val reporter = ...
reporter.enableLocationTracking()
Les mises à jour de la position sont envoyées à intervalle régulier lorsque l'état du véhicule est ONLINE
. Notez que l'appel de reporter.enableLocationTracking()
ne définit pas automatiquement l'état du véhicule sur ONLINE
. Vous devez définir l'état du véhicule explicitement.
Par défaut, l'intervalle de reporting est de 10 secondes. L'intervalle de reporting peut être modifié à l'aide de reporter.setLocationReportingInterval(long, TimeUnit)
. L'intervalle minimal de mise à jour accepté est de 5 secondes. Des mises à jour plus fréquentes peuvent ralentir les requêtes et les erreurs.
Désactivation des mises à jour de la position géographique
Une fois le travail du conducteur terminé, vous pouvez arrêter les mises à jour de la position et marquer le véhicule comme hors connexion en appelant DeliveryVehicleReporter.disableLocationTracking
ou RidesharingVehicleReporter.disableLocationTracking
.
Cet appel déclenche la planification d'une dernière mise à jour pour une livraison immédiate, qui indique que le véhicule est hors connexion. Cette mise à jour ne contiendra pas la position de l'utilisateur.
Définir l'état du véhicule
Lorsque les mises à jour de la position sont activées, si vous définissez l'état du véhicule sur ONLINE
, le véhicule est disponible pour les requêtes SearchVehicles
. De même, si vous marquez un véhicule sur OFFLINE
, il est marqué comme indisponible.
Vous avez la possibilité de définir l'état du véhicule côté serveur (consultez Mettre à jour un véhicule) ou directement dans le SDK du conducteur:
Java
RidesharingVehicleReporter reporter = ...;
reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);
Kotlin
val reporter = ...
reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)
Lorsque les mises à jour de la position sont activées, un appel à setVehicleState
est propagé lors de la prochaine mise à jour.
Si vous marquez un véhicule comme ONLINE
lorsque le suivi de la position n'est pas activé, une IllegalStateException
est générée. Un véhicule peut être marqué comme OFFLINE
lorsque le suivi de la position n'est pas encore activé ou explicitement désactivé. Cela entraîne une mise à jour immédiate. Un appel à RidesharingVehicleReporter.disableLocationTracking()
définit l'état du véhicule sur OFFLINE
.
Notez que setVehicleState
s'affiche immédiatement et que les mises à jour sont effectuées sur le thread de mise à jour de la position. Comme pour la gestion des erreurs de mise à jour de la position, les erreurs de mise à jour de l'état du véhicule sont propagées à l'aide de l'élément StatusListener
éventuellement fourni dans DriverContext
.