Premiers pas avec le SDK grand public pour Android

Vous pouvez utiliser le SDK Consumer pour créer et exécuter une application grand public de base intégrée aux services de backend de la solution On-demand Rides and Deliveries. Vous pouvez créer une application de progression du trajet et de la commande qui peut afficher un trajet actif, répondre aux mises à jour de trajet et gérer les erreurs de trajet.

Étant donné que le SDK client possède une architecture modulaire, vous pouvez utiliser les parties de l'API que vous souhaitez utiliser pour votre application et les intégrer à vos propres API, aux services de backend fournis par Fleet Engine et à d'autres API de Google Maps Platform.

Configuration système minimale requise

L'appareil mobile doit être équipé d'Android 6.0 (niveau d'API 23) ou version ultérieure.

Configuration de la compilation et des dépendances

Les versions 1.99.0 et ultérieures du SDK grand public sont disponibles dans le dépôt Maven de Google. Le canal du dépôt privé précédemment utilisé est obsolète.

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 grand public pour Android, votre application doit cibler minSdkVersion 23 ou version ultérieure.

Pour exécuter une application créée avec le SDK grand public, 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:

  1. Créez un projet dans la console Google Cloud ou sélectionnez un projet existant à utiliser avec le SDK client. Attendez quelques minutes que le nouveau projet soit visible dans la console Google Cloud.

  2. Pour 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.

  3. 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 client à votre application

Le SDK client est disponible via un dépôt Maven privé. Ce dépôt comprend les fichiers .pom (Project Object Model) du SDK, ainsi que des fichiers Javadocs. Pour ajouter le SDK client à votre application:

  1. Configurez votre environnement pour accéder au dépôt Maven hôte, comme décrit dans la section précédente.

    Si vous avez une configuration centralisée de la gestion des dépendances déclarée dans settings.gradle, désactivez-la comme suit.

    • Supprimez le bloc de code suivant dans settings.gradle:

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. 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 client.

    Gradle

    Ajoutez les éléments suivants à votre build.gradle :

    dependencies {
      ...
      implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER'
    }
    

    Maven

    Ajoutez les éléments suivants à votre pom.xml :

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-consumer</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    
  3. Le SDK grand public dépend du SDK Maps. Cette dépendance est configurée de telle sorte que si la version du SDK Maps n'est pas explicitement définie dans le fichier de configuration de compilation, comme illustré ci-dessous, lorsqu'une nouvelle version du SDK Maps est publiée, le SDK client continue à utiliser la version minimale compatible requise.

    Gradle

    Ajoutez les éléments suivants à votre build.gradle :

    dependencies {
      ...
      implementation 'com.google.android.gms:play-services-maps:18.1.0'
    }
    

    Maven

    Ajoutez les éléments suivants à votre pom.xml :

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.gms</groupId>
        <artifactId>play-services-maps</artifactId>
        <version>18.1.0</version>
      </dependency>
    </dependencies>
    

Ajouter la clé API à votre application

Une fois que vous avez ajouté le SDK client à votre application, ajoutez la clé API à votre application. Vous devez utiliser la clé API du projet que vous avez obtenue lorsque vous avez configuré votre projet de développement.

Cette section explique comment stocker votre clé API afin qu'elle puisse être référencée de manière plus sécurisée par votre application. 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 :

  1. Ouvrez votre fichier build.gradle au niveau racine et ajoutez le code suivant à l'élément dependencies sous buildscript.

    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")
        }
    }
    
  2. Ouvrez le fichier build.gradle au niveau de l'application et ajoutez le code suivant à l'élément plugins.

    Groovy

    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Si vous utilisez Android Studio, synchronisez votre projet avec Gradle.

  4. Ouvrez local.properties dans votre répertoire au niveau du projet, puis ajoutez le code suivant. Remplacez YOUR_API_KEY par votre clé API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. Dans votre fichier AndroidManifest.xml, accédez à com.google.android.geo.API_KEY et mettez à jour l'attribut android: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.consumerapidemo">
    <uses-permission android:name="android.permission.ACCESS_FINE_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 client 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 les informations sur les licences dans le fichier "third_party_licenses.txt" dans le fichier AAR désarchivé.

Consultez https://developers.google.com/android/guides/opensource pour découvrir comment inclure les notifications Open Source.

Authentification par SDK client

Le SDK Consumer fournit une authentification à l'aide de jetons Web JSON. Un jeton Web JSON (JWT, JSON Web Token) est un jeton d'accès de base JSON qui fournit une ou plusieurs revendications sur un service. Par exemple, un serveur peut générer un jeton avec la revendication "connecté en tant qu'administrateur" et le fournir à un client. Le client peut ensuite utiliser ce jeton pour prouver qu'il est connecté en tant qu'administrateur.

Le SDK client utilise le jeton Web JSON fourni par l'application pour communiquer avec Fleet Engine. Pour en savoir plus, consultez la page Authentification et autorisation Fleet Engine.

Le jeton d'autorisation doit inclure une revendication tripid:TRIP_ID dans son en-tête authorization, où TRIP_ID correspond à l'identifiant de trajet. Cela permet au SDK client d'accéder aux détails du trajet, y compris la position du véhicule, l'itinéraire et l'heure d'arrivée prévue.

Rappels de jetons Web JSON

Le SDK client enregistre un rappel de jeton d'autorisation avec l'application lors de l'initialisation. Le SDK appelle l'application afin d'obtenir un jeton pour toutes les requêtes réseau nécessitant une autorisation.

Nous vous recommandons vivement de faire en sorte que votre implémentation de rappel mette en cache les jetons d'autorisation et ne les actualise qu'une fois le délai expiry écoulé. Les jetons doivent être émis avec un délai d'expiration d'une heure.

Le rappel de jeton d'autorisation spécifie le jeton de service nécessaire pour le service TripService. Il fournit également le tripId requis pour le contexte.

L'exemple de code suivant montre comment mettre en œuvre un rappel de jeton d'autorisation.

Java

class JsonAuthTokenFactory implements AuthTokenFactory {

  private static final String TOKEN_URL =
      "https://yourauthserver.example/token";

  private static class CachedToken {
    String tokenValue;
    long expiryTimeMs;
    String tripId;
  }

  private CachedToken token;

  /*
  * This method is called on a background thread. Blocking is OK. However, be
  * aware that no information can be obtained from Fleet Engine until this
  * method returns.
  */
  @Override
  public String getToken(AuthTokenContext context) {
    // If there is no existing token or token has expired, go get a new one.
    String tripId = context.getTripId();
    if (tripId == null) {
      throw new RuntimeException("Trip ID is missing from AuthTokenContext");
    }
    if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
        !tripId.equals(token.tripId)) {
      token = fetchNewToken(tripId);
    }
    return token.tokenValue;
  }

  private static CachedToken fetchNewToken(String tripId) {
    String url = TOKEN_URL + "/" + tripId;
    CachedToken token = new CachedToken();

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();

      token.tokenValue = obj.get("ServiceToken").getAsString();
      token.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 5 minutes from that time.
      */
      token.expiryTimeMs -= 5 * 60 * 1000;
    } catch (IOException e) {
      /*
      * It's OK to throw exceptions here. The error listeners will receive the
      * error thrown here.
      */
      throw new RuntimeException("Could not get auth token", e);
    }
    token.tripId = tripId;

    return token;
  }
}

Kotlin

class JsonAuthTokenFactory : AuthTokenFactory() {

  private var token: CachedToken? = null

  /*
  * This method is called on a background thread. Blocking is OK. However, be
  * aware that no information can be obtained from Fleet Engine until this
  * method returns.
  */
  override fun getToken(context: AuthTokenContext): String {
    // If there is no existing token or token has expired, go get a new one.
    val tripId = 
      context.getTripId() ?: 
        throw RuntimeException("Trip ID is missing from AuthTokenContext")

    if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
        tripId != token.tripId) {
      token = fetchNewToken(tripId)
    }

    return token.tokenValue
  }

  class CachedToken(
    var tokenValue: String? = "", 
    var expiryTimeMs: Long = 0,
    var tripId: String? = "",
  )

  private companion object {
    const val TOKEN_URL = "https://yourauthserver.example/token"

    fun fetchNewToken(tripId: String) {
      val url = "$TOKEN_URL/$tripId"
      val token = CachedToken()

      try {
        val reader = InputStreamReader(URL(url).openStream())

        reader.use {
          val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()

          token.tokenValue = obj.get("ServiceToken").getAsString()
          token.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 5 minutes from that time.
          */
          token.expiryTimeMs -= 5 * 60 * 1000
        }
      } catch (e: IOException) {
        /*
        * It's OK to throw exceptions here. The error listeners will receive the
        * error thrown here.
        */
        throw RuntimeException("Could not get auth token", e)
      }

      token.tripId = tripId

      return token
    }
  }
}

Initialiser l'API

Avant de suivre ces procédures, nous partons du principe que vous avez activé les services appropriés et le SDK client.

Obtenir l'instance ConsumerApi

Pour utiliser le SDK client, votre application doit initialiser ConsumerApi de manière asynchrone. L'API est un singleton. La méthode d'initialisation utilise un AuthTokenFactory. La fabrique génère de nouveaux jetons JWT pour l'utilisateur si nécessaire.

providerId est l'ID de votre projet Google Cloud. Consultez le guide de l'utilisateur Fleet Engine pour en savoir plus sur la création du projet.

Votre application doit implémenter AuthTokenFactory comme décrit dans la section Authentification du SDK client.

Java

Task<ConsumerApi> consumerApiTask = ConsumerApi.initialize(
    this, "myProviderId", authTokenFactory);

consumerApiTask.addOnSuccessListener(
  consumerApi -> this.consumerApi = consumerApi);

Kotlin

val consumerApiTask =
  ConsumerApi.initialize(this, "myProviderId", authTokenFactory)

consumerApiTask?.addOnSuccessListener { consumerApi: ConsumerApi ->
  this@YourActivity.consumerApi = consumerApi
}

Initialisez le SDK Maps pour demander le moteur de rendu préféré

La version 2.0.0 du SDK grand public est compatible avec le SDK Maps pour Android 18.1.0 et versions ultérieures. Il accepte les requêtes spécifiant le moteur de rendu Google Maps préféré. Pour en savoir plus, consultez Nouveau moteur de rendu de carte(activation).

Ajouter le SDK Maps en tant que dépendance

Gradle

Ajoutez les éléments suivants à votre build.gradle :

dependencies {
  //...
  implementation "com.google.android.gms:play-services-maps:18.1.0"
}

Maven

Ajoutez les éléments suivants à votre pom.xml :

 <dependencies>
   ...
   <dependency>
     <groupId>com.google.android.gms</groupId>
     <artifactId>play-services-maps</artifactId>
     <version>18.1.0</version>
   </dependency>
 </dependencies>

Initialisez le SDK Maps avant d'initialiser le SDK grand public.

Dans votre classe Application ou Activity de démarrage, appelez MapsInitializer.initialize() et attendez le résultat de la requête du moteur de rendu avant d'initialiser le SDK Consumer.

java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  initViews();

  MapsInitializer.initialize(getApplicationContext(), Renderer.LATEST,
      new OnMapsSdkInitializedCallback() {
        @Override
        public void onMapsSdkInitialized(Renderer renderer) {
          switch (renderer) {
            case LATEST:
              Log.i("maps_renderer", "LATEST renderer");
              break;
            case LEGACY:
              Log.i("maps_renderer", "LEGACY renderer");
              break;
          }

          initializeConsumerSdk();
        }
      });
}

Kotlin

fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.main)
  initViews()

  MapsInitializer.initialize(
    getApplicationContext(), Renderer.LATEST,
    object : OnMapsSdkInitializedCallback() {
      fun onMapsSdkInitialized(renderer: Renderer?) {
        when (renderer) {
          LATEST -> Log.i("maps_renderer", "LATEST renderer")
          LEGACY -> Log.i("maps_renderer", "LEGACY renderer")
        }
        initializeConsumerSdk()
      }
    })
  }

Créer l'interface utilisateur

Vous pouvez utiliser ConsumerMapFragment ou ConsumerMapView pour créer l'interface utilisateur de votre application. ConsumerMapFragment vous permet de définir votre carte à l'aide d'un Fragment, tandis que ConsumerMapView vous permet d'utiliser un View. Les fonctionnalités de partage de course sont les mêmes dans ConsumerMapView et ConsumerMapFragment. Vous pouvez donc en choisir une selon que View ou Fragment est mieux adapté à votre application.

Prise en charge de l'API 19 (KitKat) et des drawables vectoriels.

Si la conception de votre application nécessite la prise en charge des appareils utilisant l'API 19 (KitKat) et des drawables vectoriels, ajoutez le code suivant à votre activité. Ce code étend AppCompatActivity pour utiliser les drawables vectoriels dans le SDK client.

Java

// ...
import android.support.v7.app.AppCompatActivity;

// ...

public class ConsumerTestActivity extends AppCompatActivity {
  // ...
}

Kotlin

// ...
import android.support.v7.app.AppCompatActivity

// ...

class ConsumerTestActivity : AppCompatActivity() {
  // ...
}

Ajouter le fragment ou la vue de carte

Vous créez la carte pour afficher le partage de parcours dans un fragment Android ou une vue, que vous définissez dans le fichier XML de mise en page de votre application (situé dans /res/layout). Le fragment (ou vue) donne ensuite accès à la carte de partage de trajets, que votre application peut consulter et modifier. La carte fournit également un handle vers le ConsumerController, ce qui permet à votre application de contrôler et de personnaliser l'expérience de partage de trajet.

Carte et contrôleur de partage de parcours

Vous définissez la carte de partage de parcours soit en tant que fragment (avec ConsumerMapFragment), soit en tant que vue (avec ConsumerMapView), comme illustré dans l'exemple de code suivant. Votre méthode onCreate() doit ensuite appeler getConsumerGoogleMapAsync(callback), qui renvoie ConsumerGoogleMap de manière asynchrone dans le rappel. Vous pouvez ensuite utiliser ConsumerGoogleMap pour afficher le partage du parcours. Vous pouvez le mettre à jour si nécessaire par votre application.

ConsumerMapFragment

Vous définissez le fragment dans le fichier XML de mise en page de votre application, comme illustré dans l'exemple de code suivant.

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapFragment"
    android:id="@+id/consumer_map_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

L'appel à getConsumerGoogleMapAsync() doit provenir de la méthode onCreate().

Java

public class SampleAppActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

    // Find the ConsumerMapFragment.
    ConsumerMapFragment consumerMapFragment =
        (ConsumerMapFragment) fragmentManager.findFragmentById(R.id.consumer_map_fragment);

    // Initiate the callback that returns the map.
    if (consumerMapFragment != null) {
      consumerMapFragment.getConsumerGoogleMapAsync(
          new ConsumerMapReadyCallback() {
            // The map returned in the callback is used to access the ConsumerController.
            @Override
            public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
              ConsumerController consumerController = consumerGoogleMap.getConsumerController();
            }
          });
    }
  }

}

Kotlin

class SampleAppActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    // Find the ConsumerMapFragment.
    val consumerMapFragment =
      fragmentManager.findFragmentById(R.id.consumer_map_fragment) as ConsumerMapFragment

    consumerMapFragment.getConsumerGoogleMapAsync(
      object : ConsumerMapReadyCallback() {
        override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
          val consumerController = consumerGoogleMap.getConsumerController()!!
        }
      }
    )
  }
}
ConsumerMapView

La vue peut être utilisée dans un fragment ou dans une activité, comme défini dans votre fichier XML.

<com.google.android.libraries.mapsplatform.transportation.consumer.view.ConsumerMapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/consumer_map_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

L'appel à getConsumerGoogleMapAsync() doit provenir de onCreate(). En plus du paramètre de rappel, il nécessite l'activité ou le fragment qui le contiennent, ainsi que GoogleMapOptions (qui peut être nul), contenant les attributs de configuration de MapView. La classe de base de l'activité ou du fragment doit être FragmentActivity ou Fragment de support (respectivement), car elles donnent accès à son cycle de vie.

Java

public class SampleAppActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ConsumerMapView mapView = findViewById(R.id.consumer_map_view);

    if (mapView != null) {
      mapView.getConsumerGoogleMapAsync(
          new ConsumerMapReadyCallback() {
            // The map returned in the callback is used to access the ConsumerController.
            @Override
            public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerGoogleMap) {
              ConsumerController consumerController = consumerGoogleMap.getConsumerController();
            }
          }, this, null);
    }
  }

}

Kotlin

class SampleAppActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    val mapView = findViewById(R.id.consumer_map_view) as ConsumerMapView

    mapView.getConsumerGoogleMapAsync(
      object : ConsumerMapReadyCallback() {
        // The map returned in the callback is used to access the ConsumerController.
        override fun onConsumerMapReady(consumerGoogleMap: ConsumerGoogleMap) {
          val consumerController = consumerGoogleMap.getConsumerController()!!
        }
      },
      /* fragmentActivity= */ this,
      /* googleMapOptions= */ null,
    )
  }
}

Un MapView dans un fragment est identique à l'exemple ci-dessus pour MapView dans une activité, sauf que le fragment gonfle la mise en page qui inclut le MapView dans la méthode onCreateView() du fragment.

Java

public class MapViewInFragment extends Fragment {

  @Override
  public View onCreateView(
      @NonNull LayoutInflater layoutInflater,
      @Nullable ViewGroup viewGroup,
      @Nullable Bundle bundle) {
    return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false);
  }

}

Kotlin

class MapViewInFragment : Fragment() {
  override fun onCreateView(
    layoutInflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?,
  ): View {
    return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false)
  }
}

Ajuster le zoom de l'appareil photo pour faire la mise au point sur un trajet

Le bouton "Ma position" par défaut, intégré au SDK Maps, centre la caméra sur la position de l'appareil.

Si une session de partage de trajet est active, vous pouvez centrer la caméra pour vous concentrer sur le trajet plutôt que sur la position de l'appareil.

SDK grand public pour la solution intégrée Android: AutoCamera

Pour vous permettre de vous concentrer sur le parcours plutôt que sur l'emplacement de l'appareil, le SDK Consommateur fournit une fonctionnalité AutoCamera, activée par défaut. La caméra effectue un zoom pour se concentrer sur l'itinéraire à partager et le prochain point de cheminement du trajet.

AutoCamera

Personnaliser le comportement de la caméra

Si vous avez besoin de mieux contrôler le comportement de l'appareil photo, vous pouvez désactiver ou activer la caméra automatique à l'aide de ConsumerController.setAutoCameraEnabled().

ConsumerController.getCameraUpdate() renvoie les limites d'appareil photo recommandées à ce moment. Vous pouvez ensuite fournir ce CameraUpdate en tant qu'argument à GoogleMap.moveCamera() ou GoogleMap.animateCamera().

accéder à des services de partage de course et à des cartes ;

Pour prendre en charge le partage de course et l'interaction avec la carte dans votre application, vous devez avoir accès à ConsumerGoogleMap et ConsumerController. ConsumerMapFragment et ConsumerMapView renvoient tous deux ConsumerGoogleMap de manière asynchrone dans ConsumerMapReadyCallback. ConsumerGoogleMap renvoie ConsumerController à partir de getConsumerController(). Vous pouvez accéder à ConsumerGoogleMap et ConsumerController comme suit.

Java

private ConsumerGoogleMap consumerGoogleMap;
private ConsumerController consumerController;
private ConsumerMapView consumerMapView;

consumerMapView.getConsumerGoogleMapAsync(
    new ConsumerMapReadyCallback() {
      @Override
      public void onConsumerMapReady(@NonNull ConsumerGoogleMap consumerMap) {
        consumerGoogleMap = consumerMap;
        consumerController = consumerMap.getConsumerController();
      }
    },
    this, null);

Kotlin

var consumerGoogleMap: ConsumerGoogleMap
var consumerController: ConsumerController
val consumerMapView = findViewById(R.id.consumer_map_view) as ConsumerMapView

consumerMapView.getConsumerGoogleMapAsync(
  object : ConsumerMapReadyCallback() {
    override fun onConsumerMapReady(consumerMap: ConsumerGoogleMap) {
      consumerGoogleMap = consumerMap
      consumerController = consumerMap.getConsumerController()
    },
    /* fragmentActivity= */ this,
    /* googleMapOptions= */ null,
  }
)

ConsumerGoogleMap

ConsumerGoogleMap est une classe wrapper pour la classe GoogleMap. Elle permet à votre application d'interagir avec la carte à l'aide d'une API équivalente à GoogleMap. L'utilisation de la carte grand public permet à votre application et à votre service de partage de course d'interagir de manière transparente avec la même carte GoogleMap sous-jacente. Par exemple, GoogleMap n'autorise qu'un seul enregistrement de rappel, mais ConsumerGoogleMap accepte les deux rappels enregistrés. Ces rappels permettent à votre application et à votre service de covoiturage d'enregistrer des rappels qui sont appelés de manière séquentielle.

ConsumerController

ConsumerController permet d'accéder à des fonctionnalités de partage de course, telles que la surveillance des trajets, le contrôle de l'état des trajets et la définition de lieux.

Configurer le partage de parcours

Une fois que le backend a mis en correspondance un consommateur avec un véhicule, utilisez JourneySharingSession pour démarrer l'interface utilisateur de partage de parcours. Le partage de parcours affiche l'emplacement et l'itinéraire du véhicule correspondant. Après avoir implémenté le SDK dans votre application, vous pouvez ajouter la fonctionnalité permettant de surveiller les trajets, d'écouter les mises à jour et de gérer les erreurs. Les procédures suivantes supposent que les services de backend sont en place et que vos services de mise en correspondance des consommateurs avec les véhicules sont opérationnels.

  1. Enregistrez un écouteur sur un objet TripModel pour obtenir des détails sur le trajet, tels que l'heure d'arrivée prévue estimée et la distance que le véhicule doit parcourir avant l'arrivée.

    Java

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    String tripName = ...;
    TripModelManager tripModelManager = consumerApi.getTripModelManager();
    TripModel tripModel = tripModelManager.getTripModel(tripName);
    
    // Create a JourneySharingSession instance based on the TripModel.
    JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session);
    
    // Register for trip update events.
    tripModel.registerTripCallback(new TripModelCallback() {
      @Override
      public void onTripETAToNextWaypointUpdated(
          TripInfo tripInfo, @Nullable Long timestampMillis) {
        // ...
      }
    
      @Override
      public void onTripActiveRouteRemainingDistanceUpdated(
          TripInfo tripInfo, @Nullable Integer distanceMeters) {
        // ...
      }
    
      // ...
    });
    

    Kotlin

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    val tripName = "tripName"
    val tripModelManager = consumerApi.getTripModelManager()
    val tripModel = tripModelManager.getTripModel(tripName)
    
    // Create a JourneySharingSession instance based on the TripModel.
    val session = JourneySharingSession.createInstance(tripModel)
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session)
    
    // Register for trip update events.
    tripModel.registerTripCallback(
      object : TripModelCallback() {
        override fun onTripETAToNextWaypointUpdated(
          tripInfo: TripInfo,
          timestampMillis: Long?,
        ) {
          // ...
        }
    
        override fun onTripActiveRouteRemainingDistanceUpdated(
          tripInfo: TripInfo,
          distanceMeters: Int?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. Configurez votre trajet avec TripModelOptions.

    Java

    // Set refresh interval to 2 seconds.
    TripModelOptions tripOptions =
        TripModelOptions.builder().setRefreshIntervalMillis(2000).build();
    tripModel.setTripModelOptions(tripOptions);
    

    Kotlin

    // Set refresh interval to 2 seconds.
    val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build()
    tripModel.setTripModelOptions(tripOptions)
    

Arrêter le partage de trajet

Veillez à mettre fin au partage de parcours lorsqu'il n'est plus nécessaire, par exemple lorsque l'activité de l'hôte est détruite. L'arrêt du partage de parcours interrompt également les requêtes réseau envoyées à Fleet Engine et évite les fuites de mémoire.

L'exemple de code suivant montre comment arrêter le partage de trajet.

Java

public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {

  // Class implementation

  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}

Kotlin

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

Gérer les erreurs de trajet

La méthode onTripRefreshError détecte les erreurs qui se produisent lors de la surveillance du trajet. Le mappage des erreurs du SDK Consumer suit les mêmes consignes HTTP/RPC que celles définies pour Google Cloud Platform. Erreurs courantes lors de la surveillance des trajets:

HTTP RPC Description
400 INVALID_ARGUMENT Le client a spécifié un nom de trajet incorrect. Le nom du trajet doit respecter le format providers/{provider_id}/trips/{trip_id}. provider_id doit être l'ID du projet Cloud appartenant au fournisseur de services.
401 UNAUTHENTICATED La requête n'a pas été authentifiée en raison d'un jeton JWT non valide. Cette erreur se produit si le jeton JWT est signé sans identifiant de trajet ou si le jeton JWT a expiré.
403 PERMISSION_DENIED Le client ne dispose pas des autorisations suffisantes. Cette erreur se produit si le jeton JWT n'est pas valide, si le client ne dispose pas de l'autorisation requise ou si l'API n'est pas activée pour le projet client. Le jeton JWT est peut-être manquant ou il est signé avec un identifiant de trajet qui ne correspond pas à l'identifiant de trajet demandé.
429 RESOURCE_EXHAUSTED Le quota de ressources est égal à zéro ou le taux de trafic dépasse la limite.
503 UNAVAILABLE Service indisponible. Généralement, le serveur est en panne.
504 DEADLINE_EXCEEDED Délai de requête dépassé. Cela ne se produira que si l'appelant définit un délai plus court que le délai par défaut de la méthode (c'est-à-dire que le délai demandé n'est pas suffisant pour que le serveur traite la requête) et que la requête n'a pas abouti dans le délai imparti.

Pour en savoir plus, consultez la page Gestion des erreurs du SDK client.