Introduzione all'SDK Consumer per Android

Puoi usare l'SDK consumer per creare ed eseguire un'app consumer di base integrata con i servizi di backend On-demand Rides and Deliveries Solution. Puoi creare un'app Trip and Order Progress che può visualizzare una corsa attiva, rispondere agli aggiornamenti della corsa e gestire gli errori di viaggio.

Poiché l'SDK consumer ha un'architettura modulare, puoi utilizzare le parti dell'API che vuoi utilizzare per una determinata app e integrarle con le tue API, con i servizi di backend forniti da Fleet Engine e con le API aggiuntive di Google Maps Platform.

Requisiti minimi di sistema

Sul dispositivo mobile deve essere installato Android 6.0 (livello API 23) o versioni successive.

Configurazione e configurazione delle dipendenze

Le versioni dell'SDK consumer 1.99.0 e successive sono disponibili utilizzando il repository Maven di Google. Il canale del repository privato utilizzato in precedenza è stato deprecato.

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 consumer per Android, la tua app deve avere come target minSdkVersion 23 o versioni successive.

Per eseguire un'app creata con l'SDK consumer, sul dispositivo Android deve essere installato Google Play Services.

Configura il progetto di sviluppo

Per configurare il progetto di sviluppo e ottenere una chiave API per il progetto nella console Google Cloud:

  1. Crea un nuovo progetto della console Google Cloud o selezionane uno esistente da utilizzare con l'SDK consumer. Attendi qualche minuto finché il nuovo progetto non è visibile nella console Google Cloud.

  2. Per eseguire l'app demo, il tuo progetto deve avere accesso a Maps SDK for Android. Nella console Google Cloud, seleziona API e servizi > Libreria, quindi cerca e abilita Maps SDK for Android.

  3. Ottieni una chiave API per il progetto selezionando API e servizi > Credenziali > Crea credenziali > Chiave API. Per saperne di più su come ottenere una chiave API, consulta Ottenere una chiave API.

Aggiungi l'SDK per consumatori alla tua app

L'SDK consumer è disponibile tramite un repository Maven privato. Il repository include i file Project Object Model (.pom) e Javadocs dell'SDK. Per aggiungere l'SDK per consumatori alla tua app:

  1. Configura il tuo ambiente per accedere al Repository Maven dell'host come descritto nella sezione precedente.

    Se hai dichiarato la configurazione centralizzata della gestione delle dipendenze in settings.gradle, disabilitala come segue.

    • Rimuovi il seguente blocco di codice in settings.gradle:

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. Aggiungi la seguente dipendenza alla configurazione Gradle o Maven, sostituendo il segnaposto VERSION_NUMBER con la versione desiderata dell'SDK Consumer.

    Gradle

    Aggiungi il seguente codice a build.gradle:

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

    Maven

    Aggiungi il seguente codice a pom.xml:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-consumer</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    
  3. L'SDK per i consumatori dipende dall'SDK Maps. Questa dipendenza è configurata in modo tale che, se la versione di Maps SDK non è esplicitamente definita nel file di configurazione della build come segue, quando viene rilasciata una nuova versione dell'SDK Maps, l'SDK Consumer continua a utilizzare la versione minima supportata dell'SDK di Maps richiesta.

    Gradle

    Aggiungi il seguente codice a build.gradle:

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

    Maven

    Aggiungi il seguente codice a pom.xml:

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

Aggiungi la chiave API all'app

Dopo aver aggiunto l'SDK consumer alla tua app, aggiungi la chiave API all'app. Devi utilizzare la chiave API del progetto che hai ottenuto durante la configurazione del progetto di sviluppo.

Questa sezione descrive come archiviare la chiave API in modo che la tua app possa fare riferimento in modo più sicuro. Non controllare la chiave API nel sistema di controllo della versione. Dovrebbe essere archiviato nel file local.properties, che si trova nella directory radice del progetto. Per ulteriori informazioni sul file local.properties, consulta la sezione File delle proprietà di Gradle.

Per semplificare questa attività, puoi utilizzare il plug-in Secrets Gradle per Android.

Per installare il plug-in e memorizzare la chiave API:

  1. Apri il file build.gradle di livello principale e aggiungi il seguente codice all'elemento dependencies in buildscript.

    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")
        }
    }
    
  2. Apri il file build.gradle a livello di app e aggiungi il seguente codice all'elemento plugins.

    Trendy

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

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Se utilizzi Android Studio, sincronizza il progetto con Gradle.

  4. Apri local.properties nella directory a livello di progetto, quindi aggiungi il codice seguente. Sostituisci YOUR_API_KEY con la tua chiave API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. Nel file AndroidManifest.xml, vai a com.google.android.geo.API_KEY e aggiorna l'attributo android: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.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>

Includi le attribuzioni richieste nella tua app

Se utilizzi l'SDK per i consumatori nella tua app, devi includere il testo dell'attribuzione e le licenze open source nella sezione delle note legali dell'app. È preferibile includere le attribuzioni come voce di menu indipendente o come parte di una voce di menu Informazioni.

Le informazioni sulle licenze sono disponibili nel file "third_party_licenses.txt" del file AAR non archiviato.

Per informazioni su come includere notifiche open source, consulta la pagina https://developers.google.com/android/guides/opensource.

Autenticazione SDK consumer

L'SDK consumer fornisce l'autenticazione mediante token web JSON. Un token JWT (JSON Web Token) è un token di accesso basato su JSON che fornisce una o più attestazioni su un servizio. Ad esempio, un server potrebbe generare un token con la dichiarazione "aveta eseguito l'accesso come amministratore" e fornirlo a un client. Il client può quindi usare quel token per provare che ha eseguito l'accesso come amministratore.

L'SDK consumer utilizza il token web JSON fornito dall'applicazione per comunicare con Fleet Engine. Per ulteriori informazioni, vedi Autenticazione e autorizzazione di Fleet Engine.

Il token di autorizzazione deve includere un'attestazione tripid:TRIP_ID nell'intestazione authorization del token, dove TRIP_ID è l'ID della corsa. In questo modo l'SDK consumer può accedere ai dettagli della corsa, tra cui posizione del veicolo, percorso e orario di arrivo stimato.

Callback JSON Web Token

L'SDK consumer registra un callback del token di autorizzazione con l'applicazione durante l'inizializzazione. L'SDK chiama l'applicazione per ottenere un token per tutte le richieste di rete che richiedono l'autorizzazione.

Ti consigliamo vivamente di memorizzare nella cache i token di autorizzazione dell'implementazione del callback e di aggiornarli solo una volta trascorso il tempo di expiry. I token devono essere emessi con una scadenza di un'ora.

Il callback del token di autorizzazione specifica quale token di servizio è necessario per il servizio TripService. Fornisce inoltre gli attributi tripId necessari per il contesto.

Il seguente esempio di codice mostra come implementare un callback per token di autorizzazione.

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
    }
  }
}

Inizializzare l'API

Prima di seguire queste procedure, si presume che tu abbia abilitato i servizi appropriati e l'SDK consumer.

Ottieni l'istanza ConsumerApi

Per utilizzare l'SDK consumer, la tua app deve essere inizializzata ConsumerApi in modo asincrono. L'API è un singleton. Il metodo di inizializzazione richiede un AuthTokenFactory. Quando necessario, il produttore genera nuovi token JWT per l'utente.

providerId è l'ID progetto del tuo progetto Google Cloud. Consulta la guida dell'utente di Fleet Engine per ulteriori informazioni sulla creazione del progetto.

L'app deve implementare AuthTokenFactory come descritto in Autenticazione SDK del consumatore.

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
}

Inizializza l'SDK Maps per richiedere il renderer preferito

L'SDK consumer v2.0.0 supporta l'SDK Maps per Android 18.1.0 e versioni successive. Supporta le richieste che specificano il renderer di Google Maps preferito. Per maggiori dettagli, consulta Nuovo renderer della mappa(attivazione).

Aggiungi Maps SDK come dipendenza

Gradle

Aggiungi il seguente codice a build.gradle:

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

Maven

Aggiungi il seguente codice a pom.xml:

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

Inizializza l'SDK Maps prima di inizializzare l'SDK consumer

Nella classe Application o Activity di avvio, chiama MapsInitializer.initialize() e attendi il risultato della richiesta del renderer prima di inizializzare l'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()
      }
    })
  }

Crea l'interfaccia utente

Puoi utilizzare ConsumerMapFragment o ConsumerMapView per creare l'interfaccia utente per la tua applicazione. Con ConsumerMapFragment puoi definire la mappa utilizzando un elemento Fragment, mentre con ConsumerMapView puoi utilizzare View. La funzionalità di condivisione delle corse è la stessa sia in ConsumerMapView che in ConsumerMapFragment, quindi puoi sceglierne una a seconda che View o Fragment sia più adatta alla tua applicazione.

Aggiunta del supporto per i disegnabili API 19 (Marshmallow) e Vector

Se la struttura dell'app richiede il supporto per i dispositivi API 19 (Lollipop) e gli elementi di disegno vettoriali, aggiungi il codice seguente all'attività. Questo codice estende AppCompatActivity per utilizzare il disegno Vector nell'SDK consumer.

Java

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

// ...

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

Kotlin

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

// ...

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

Aggiungere la visualizzazione o il frammento di mappa

Crea la mappa per mostrare la condivisione del percorso in un frammento Android o in una vista, che definisci nel file XML del layout dell'applicazione (situato in /res/layout). Il frammento (o la vista) fornisce quindi accesso alla mappa di condivisione del percorso, a cui la tua app può accedere e modificare. La mappa fornisce anche un handle a ConsumerController, che consente alla tua app di controllare e personalizzare l'esperienza di condivisione del percorso.

Mappa e controller di condivisione del percorso

Puoi definire la mappa di condivisione del percorso come frammento (utilizzando ConsumerMapFragment) o come vista (utilizzando ConsumerMapView), come mostrato nel seguente esempio di codice. Il tuo metodo onCreate() deve quindi chiamare getConsumerGoogleMapAsync(callback), che restituisce ConsumerGoogleMap in modo asincrono nel callback. Puoi quindi utilizzare ConsumerGoogleMap per visualizzare la condivisione del percorso, che può essere aggiornata in base alle esigenze della tua app.

ConsumerMapFragment

Devi definire il frammento nel file XML del layout dell'applicazione, come mostrato nell'esempio di codice che segue.

<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" />

La chiamata a getConsumerGoogleMapAsync() deve provenire dal metodo 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 visualizzazione può essere utilizzata in un frammento o in un'attività, come definito nel tuo file 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" />

La chiamata a getConsumerGoogleMapAsync() deve provenire da onCreate(). Oltre al parametro di callback, richiede l'attività o il frammento contenente e GoogleMapOptions (che può essere nullo), contenente gli attributi di configurazione per MapView. La classe base dell'attività o del frammento deve essere rispettivamente FragmentActivity o Fragment di assistenza, poiché fornisce accesso al suo ciclo di vita.

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 in un frammento è uguale all'esempio precedente per MapView in un'attività, ad eccezione del fatto che il frammento aumenta il layout che include MapView nel metodo del frammento onCreateView().

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)
  }
}

Regolare lo zoom della fotocamera per mettere a fuoco un viaggio

Il pulsante La mia posizione predefinito in Maps SDK centra la fotocamera sulla posizione del dispositivo.

Se è attiva una sessione di condivisione del percorso, ti consigliamo di centrare la fotocamera in modo che si concentri sul percorso anziché sulla posizione del dispositivo.

SDK consumer per soluzione integrata per Android: AutoFotocamera

Per consentirti di concentrarti sul percorso anziché sulla posizione del dispositivo, l'SDK per i consumatori fornisce una funzionalità AutoFotocamera abilitata per impostazione predefinita. Lo zoom della fotocamera mette a fuoco il percorso che condivide il percorso e la tappa successiva.

AutoCamera

Personalizzazione del comportamento della videocamera

Se hai bisogno di un maggiore controllo sul comportamento della videocamera, puoi disattivare o attivare la fotocamera automatica utilizzando ConsumerController.setAutoCameraEnabled().

ConsumerController.getCameraUpdate() restituisce i limiti della fotocamera consigliati in quel momento. Puoi quindi fornire questo CameraUpdate come argomento per GoogleMap.moveCamera() o GoogleMap.animateCamera().

Accedi a ridesharing e mappe

Per supportare il ridesharing e l'interazione con la mappa nella tua applicazione, devi avere accesso a ConsumerGoogleMap e ConsumerController. ConsumerMapFragment e ConsumerMapView restituiscono entrambi ConsumerGoogleMap in modo asincrono in ConsumerMapReadyCallback. ConsumerGoogleMap resi ConsumerController a partire da getConsumerController(). Puoi accedere a ConsumerGoogleMap e ConsumerController nel seguente modo.

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 è una classe wrapper per la classe GoogleMap. Fornisce alla tua app la possibilità di interagire con la mappa utilizzando un'API equivalente a GoogleMap. L'uso della mappa consumer consente all'app e al ride sharing di interagire senza problemi con la stessa mappa Google. Ad esempio, GoogleMap consente una sola registrazione di callback, ma ConsumerGoogleMap supporta i callback con doppia registrazione. Questi callback consentono alla tua app e al ride sharing di registrare i callback che vengono chiamati in sequenza.

ConsumerController

ConsumerController consente di accedere a funzionalità di condivisione delle corse, tra cui il monitoraggio delle corse, il controllo dello stato delle corse e l'impostazione delle località.

Configura la condivisione del percorso

Dopo che il backend ha associato un consumatore a un veicolo, utilizza JourneySharingSession per iniziare l'interfaccia utente di condivisione del percorso. La condivisione del percorso mostra la posizione e il percorso del veicolo corrispondenti. Dopo aver implementato l'SDK nella tua app, puoi aggiungere la funzionalità per il monitoraggio dei viaggi, l'ascolto di aggiornamenti e la gestione degli errori. Le procedure seguenti presuppongono che i servizi di backend siano attivi e che i servizi per l'abbinamento dei consumatori ai veicoli siano operativi.

  1. Registra un ascoltatore su un oggetto TripModel per ottenere dettagli sulla corsa, come l'orario di arrivo stimato e la distanza che il veicolo deve percorrere prima dell'arrivo.

    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. Configura il percorso con 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)
    

Interrompi la condivisione del percorso

Assicurati di interrompere la condivisione del percorso quando non è più necessaria, ad esempio quando viene eliminata l'attività host. L'interruzione della condivisione del percorso interrompe anche le richieste di rete a Fleet Engine e impedisce le fughe di memoria.

Il seguente codice di esempio mostra come interrompere la condivisione del percorso.

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()
  }
}

Gestire gli errori di percorso

Il metodo onTripRefreshError segnala gli errori che si verificano durante il monitoraggio della corsa. La mappatura degli errori dell'SDK consumer segue le stesse linee guida HTTP/RPC stabilite per Google Cloud Platform. Di seguito sono riportati alcuni errori comuni che emergono durante il monitoraggio della corsa:

HTTP RPC Descrizione
400 INVALID_ARGUMENT Il cliente ha specificato un nome di viaggio non valido. Il nome della corsa deve essere nel formato providers/{provider_id}/trips/{trip_id}. Il provider_id deve essere l'ID del progetto Cloud di proprietà del fornitore di servizi.
401 NON AUTENTICATO Richiesta non autenticata a causa di un token JWT non valido. Questo errore si verifica se il token JWT è firmato senza un tripid o se il token JWT è scaduto.
403 PERMISSION_DENIED Il client non dispone di autorizzazioni sufficienti. Questo errore si verifica se il token JWT non è valido, il client non dispone dell'autorizzazione o se l'API non è abilitata per il progetto client. Il token JWT potrebbe non essere presente o è firmato con un ID di corsa che non corrisponde all'ID della corsa richiesto.
429 RESOURCE_EXHAUSTED La quota di risorse è pari a zero o la frequenza di traffico supera il limite.
503 UNAVAILABLE Servizio non disponibile. In genere il server non è attivo.
504 DEADLINE_EXCEEDED Scadenza della richiesta superata. Ciò si verifica solo se il chiamante imposta una scadenza più breve della scadenza predefinita del metodo (ad esempio, la scadenza richiesta non è sufficiente affinché il server elabori la richiesta) e la richiesta non è stata completata entro la scadenza.

Per maggiori informazioni, consulta Gestione degli errori dell'SDK consumer.