On-Demand-Lösungen für Fahrten und Lieferungen sind derzeit nur für ausgewählte Partner verfügbar.

Erste Schritte mit dem Consumer SDK für Android

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Sie können das Consumer SDK verwenden, um eine einfache Nutzeranwendung zu erstellen und auszuführen, die in On-Demand-Back-End-Dienste der Kategorie „Fahrten und Lieferungen“ eingebunden ist. Sie können eine Fahrt- und Bestellfortschritt-App erstellen, die eine aktive Fahrt anzeigt, auf Fahrtaktualisierungen reagiert und Fahrtfehler verarbeitet.

Da das Consumer SDK eine modulare Architektur hat, können Sie die Teile der API, die Sie für die jeweilige App verwenden möchten, in Ihre eigenen APIs, Back-End-Dienste der Fleet Engine und zusätzliche APIs der Google Maps Platform einbinden.

Mindestsystemanforderungen

Auf dem Mobilgerät muss Android 5.0 (API-Level 21) oder höher installiert sein.

Voraussetzungen

Transport- und Logistik-SDKs für Android werden in einem Artifact Registry-Maven-Repository veröffentlicht. Das Repository enthält die SDK-Dateien für Projektobjekte (.pom) und Offline-Javadocs.

Zugriff erhalten

Wenn Sie Google Workspace-Kunde sind, erstellen Sie während der Einrichtung eine Workspace-Gruppe wie google-maps-platform-sdk-users@workspacedomain.com und geben Sie den Namen an Google weiter. Dies ist der empfohlene Ansatz. Ihre Arbeitsbereichsgruppe wird dann einer Zulassungsliste hinzugefügt, die Zugriff auf das Maven-Repository gmp-artifacts/transportation gewährt. Prüfen Sie, ob die E-Mail-Adressen der Nutzer und Dienstkonten, die Zugriff benötigen, in dieser Liste enthalten sind.

Wenn Ihre Organisation keine Workspace-Gruppen erstellen kann, senden Sie eine Liste der E-Mail-Adressen von Nutzern und Dienstkonten, die Zugriff auf diese Artefakte benötigen, an Google.

Lokale Entwicklung

Für die lokale Entwicklung reicht es aus, sich mit dem Cloud SDK anzumelden.

gcloud

gcloud auth login

Die für die Anmeldung verwendete E-Mail-Adresse muss Mitglied der Workspace-Gruppe sein.

Automatisierung (Build-Systeme oder Continuous Integration)

Richten Sie Ihre Automatisierungshosts gemäß den Best Practices ein:

  • Wenn der Prozess in einer Google Cloud-Umgebung ausgeführt wird, nutzen Sie die automatische Erkennung von Anmeldedaten.

  • Andernfalls speichern Sie die Schlüsseldatei des Dienstkontos an einem sicheren Ort im Dateisystem des Hosts und legen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS entsprechend fest.

Die E-Mail-Adresse des Dienstkontos, das mit den Anmeldedaten verknüpft ist, muss Mitglied der Workspace-Gruppe sein.

Konfiguration

Konfigurieren Sie Maven oder Gradle so, dass Nutzer- oder Dienstanmeldedaten automatisch erkannt werden.

Gradle

Fügen Sie der Datei build.gradle Ihres Anwendungsmoduls Folgendes hinzu, nicht der Datei build.gradle des Projektstammmoduls:

plugins {
  id "com.google.cloud.artifactregistry.gradle-plugin" version "2.1.5"
}
repositories {
  maven {
    url "artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation"
  }
}

Maven

Fügen Sie zum pom.xml Folgendes hinzu:

<repositories>
  <repository>
    <id>gmp-artifacts</id>
    <url>artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation</url>
    <releases>
      <enabled>true</enabled>
    </releases>
  </repository>
</repositories>
<build>
  <extensions>
    <extension>
      <groupId>com.google.cloud.artifactregistry</groupId>
      <artifactId>artifactregistry-maven-wagon</artifactId>
      <version>2.1.5</version>
    </extension>
  </extensions>
</build>

Informationen zum Überprüfen des Zugriffs finden Sie unter Java-Pakete verwalten.

Projektkonfiguration

Damit du das Consumer SDK für Android verwenden kannst, muss die App auf minSdkVersion 19 oder höher ausgerichtet sein.

Zum Ausführen einer mit dem Consumer SDK erstellten App müssen auf dem Android-Gerät Google Play-Dienste installiert sein.

Entwicklungsprojekt einrichten

So richten Sie Ihr Entwicklungsprojekt ein und rufen einen API-Schlüssel für das Projekt in der Google Cloud Console ab:

  1. Erstellen Sie ein neues Google Cloud Console-Projekt oder wählen Sie ein vorhandenes Projekt für die Verwendung mit dem Consumer SDK aus. Warten Sie einige Minuten, bis das neue Projekt in der Google Cloud Console sichtbar ist.

  2. Damit Sie die Demo-App ausführen können, muss Ihr Projekt Zugriff auf das Maps SDK for Android haben. Wählen Sie in der Google Cloud Console APIs und Dienste & gt; Bibliothek aus und suchen Sie dann nach dem Maps SDK for Android und aktivieren Sie es.

  3. Rufen Sie einen API-Schlüssel für das Projekt ab, indem Sie APIs und Dienste > Anmeldedaten > Anmeldedaten erstellen > API-Schlüssel auswählen. Weitere Informationen zum Abrufen eines API-Schlüssels finden Sie unter API-Schlüssel abrufen.

Consumer SDK zu Ihrer App hinzufügen

Das Consumer SDK ist über ein privates Maven-Repository verfügbar. Das Repository enthält die Projektobjektmodell-Dateien (.pom) des SDK und Javadocs. So fügen Sie das Consumer SDK Ihrer App hinzu:

  1. Richten Sie Ihre Umgebung für den Zugriff auf das Host-Maven-Repository ein, wie unter Zugriff erhalten beschrieben.

    Wenn Sie eine zentrale Konfiguration für das Abhängigkeitsmanagement in settings.gradle deklariert haben, deaktivieren Sie sie so:

    • Entfernen Sie den folgenden Codeblock in settings.gradle:

      import org.gradle.api.initialization.resolve.RepositoriesMode
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
          }
      }
      
  2. Fügen Sie der Gradle- oder Maven-Konfiguration die folgende Abhängigkeit hinzu. Ersetzen Sie dabei den Platzhalter VERSION_NUMBER durch die gewünschte Version des Consumer SDK.

    Gradle

    Fügen Sie zum build.gradle Folgendes hinzu:

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

    Maven

    Fügen Sie zum pom.xml Folgendes hinzu:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-consumer</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    

API-Schlüssel in App einfügen

Nachdem Sie das Consumer SDK zu Ihrer App hinzugefügt haben, fügen Sie den API-Schlüssel zu Ihrer App hinzu. Sie müssen den Projekt-API-Schlüssel verwenden, den Sie bei der Einrichtung Ihres Entwicklungsprojekts erhalten haben.

In diesem Abschnitt wird beschrieben, wie du deinen API-Schlüssel speicherst, damit er von deiner App sicherer referenziert werden kann. Er sollte nicht in dein Versionsverwaltungssystem eingecheckt werden. Sie sollte in der Datei local.properties gespeichert sein, die sich im Stammverzeichnis Ihres Projekts befindet. Weitere Informationen zur Datei local.properties finden Sie unter Gradle-Attributdateien.

Sie können das Secrets Gradle Plugin for Android verwenden, um diese Aufgabe zu optimieren.

So installieren Sie das Plug-in und speichern Ihren API-Schlüssel:

  1. Öffnen Sie die Datei build.gradle auf Stammebene und fügen Sie dem Element dependencies unter buildscript den folgenden Code hinzu.

    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. Öffnen Sie die Datei build.gradle auf App-Ebene und fügen Sie dem Element plugins den folgenden Code hinzu.

    Groovy

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

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Wenn Sie Android Studio verwenden, synchronisieren Sie Ihr Projekt mit Gradle.

  4. Öffnen Sie local.properties im Verzeichnis auf Projektebene und fügen Sie dann den folgenden Code hinzu. ersetzen Sie dabei YOUR_API_KEY durch Ihren eigenen API-Schlüssel:

    MAPS_API_KEY=YOUR_API_KEY
    
  5. Rufen Sie in der Datei AndroidManifest.xml com.google.android.geo.API_KEY auf und aktualisieren Sie das Attribut android:value so:

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="${MAPS_API_KEY}" />
    

Das folgende Beispiel zeigt ein vollständiges Manifest für eine Beispielanwendung:

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

Erforderliche Attributionen in die App aufnehmen

Wenn Sie das Consumer SDK in Ihrer App verwenden, müssen Sie im Abschnitt „Rechtliche Hinweise“ Ihrer App Attributionstext und Open-Source-Lizenzen angeben. Am besten fügen Sie die Quellenangaben als eigenständiges Menüelement oder als Teil eines Info-Menüelements hinzu.

Sie finden den erforderlichen Attributionstext und die Open-Source-Lizenzen in der ZIP-Datei Ridesharing Consumer SDK:

  • NOTICE.txt
  • LICENSES.txt

Consumer SDK-Authentifizierung

Das Consumer SDK bietet eine Authentifizierung mithilfe von JSON-Webtokens. Ein JSON-Webtoken (JWT) ist ein JSON-basiertes Zugriffstoken, das einen oder mehrere Ansprüche auf einen Dienst bereitstellt. Ein Server könnte beispielsweise ein Token generieren, das die Anforderung „als Administrator angemeldet“ enthält, und diese Information an einen Client senden. Der Client könnte dann mit diesem Token nachweisen, dass er als Administrator angemeldet ist.

Das Consumer SDK verwendet das von der Anwendung bereitgestellte JSON-Webtoken, um mit der Fleet Engine zu kommunizieren. Weitere Informationen finden Sie unter Fleet Engine-Authentifizierung und -Autorisierung.

Das Autorisierungstoken bietet Zugriff auf die folgenden Fleet Engine-Dienste:

  • TripService – Gewährt dem Consumer SDK Zugriff auf Fahrtdetails, einschließlich Fahrzeugposition, Route und voraussichtliche Ankunftszeit. Autorisierungstokens für den Fahrtdienst müssen eine tripid:TRIP_ID-Anforderung im authorization-Header des Tokens enthalten, wobei TRIP_ID die Fahrt-ID ist.
  • VehicleService: Liefert dem Consumer SDK Informationen zum Standort der Fuzz-Fahrzeuge, um die Fahrzeugdichteebene anzuzeigen und die voraussichtlichen Ankunftszeiten zu schätzen. Da das Consumer SDK nur fuzzierte Standorte verwendet, muss für Autorisierungstoken für den Fahrzeugdienst keine vehicleid-Anforderung ausgeführt werden.

Callbacks für JSON-Webtoken

Das Consumer SDK registriert während der Initialisierung einen Autorisierungstoken-Callback bei der Anwendung. Das SDK ruft die Anwendung auf, um ein Token für alle Netzwerkanfragen abzurufen, die autorisiert werden müssen.

Wir empfehlen dringend, Autorisierungstokens für die Callback-Implementierung zu aktualisieren und nur zu aktualisieren, wenn die expiry-Zeit verstrichen ist. Tokens sollten mit einer Laufzeit von einer Stunde ausgestellt werden.

Der Callback für das Autorisierungstoken gibt an, welches Diensttoken für den Dienst TripService benötigt wird. Außerdem stellt es die erforderlichen tripId für den Kontext bereit.

Das folgende Codebeispiel zeigt, wie Sie einen Autorisierungstoken-Callback implementieren.

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

API initialisieren

Es wird vorausgesetzt, dass Sie die entsprechenden Dienste und das Consumer SDK aktiviert haben.

ConsumerApi-Instanz abrufen

Ihre App muss ConsumerApi asynchron initialisieren, um das Consumer SDK zu verwenden. Die API ist ein Singleton. Für die Initialisierungsmethode ist AuthTokenFactory erforderlich. Die Factory generiert bei Bedarf neue JWT-Tokens für den Nutzer.

providerId ist die Projekt-ID Ihres Google Cloud-Projekts. Weitere Informationen zum Erstellen des Projekts finden Sie im Fleet Engine-Nutzerhandbuch.

In deiner App sollte AuthTokenFactory wie unter Authentifizierung des Consumer SDK beschrieben implementiert sein.

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
}

Benutzeroberfläche erstellen

Sie können entweder ConsumerMapFragment oder ConsumerMapView verwenden, um die Benutzeroberfläche für Ihre Anwendung zu erstellen. Mit ConsumerMapFragment kannst du deine Karte mit einem Fragment definieren, mit ConsumerMapView ein View. Die Fahrgemeinschaftsfunktion ist in ConsumerMapView und ConsumerMapFragment identisch. Sie können also eine davon auswählen, je nachdem, ob View oder Fragment für Ihre Anwendung besser geeignet ist.

Unterstützung für API 19- (KitKat) und Vector-Drawables hinzugefügt

Wenn dein App-Design Unterstützung für API-19-Geräte (KitKat) und Vektor-Drawables benötigt, füge deiner Aktivität den folgenden Code hinzu. Dieser Code erweitert AppCompatActivity, um die Vector-Drawables im Consumer SDK zu verwenden.

Java

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

// ...

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

Kotlin

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

// ...

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

Kartenfragment oder Ansicht hinzufügen

Sie erstellen die Karte zum Anzeigen von Wegfreigaben entweder in einem Android-Fragment oder in einer Ansicht, die Sie in der XML-Datei Ihres Anwendungslayouts (in /res/layout) definiert haben. Das Fragment (oder die Ansicht) bietet dann Zugriff auf die Karte zum Teilen von Routen, auf die Ihre App zugreifen und diese ändern kann. Auf der Karte wird auch ein Ziehpunkt für die ConsumerController angezeigt, über die die App das Teilen von Reisen steuern und anpassen kann.

Kaufprozess mit Karte und Controller

Sie definieren die Karte zum Teilen der Route entweder als Fragment (mit ConsumerMapFragment) oder als Ansicht (mit ConsumerMapView), wie im folgenden Codebeispiel gezeigt. Die Methode onCreate() sollte dann getConsumerGoogleMapAsync(callback) aufrufen, wodurch ConsumerGoogleMap im Callback asynchron zurückgegeben wird. Anschließend verwenden Sie ConsumerGoogleMap, um das Teilen der Onlinerecherche anzuzeigen. Es kann nach Bedarf von Ihrer App aktualisiert werden.

Verbraucherkartenfragment

Sie definieren das Fragment in der XML-Datei für das Anwendungslayout, wie im folgenden Codebeispiel gezeigt.

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

Der Aufruf von getConsumerGoogleMapAsync() sollte aus der Methode onCreate() stammen.

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()!!
        }
      }
    )
  }
}
Verbraucher-Kartenansicht

Die Ansicht kann entweder in einem Fragment oder in einer Aktivität verwendet werden, wie in Ihrer XML-Datei definiert.

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

Der Aufruf von getConsumerGoogleMapAsync() sollte von onCreate() aus erfolgen. Zusätzlich zum Callback-Parameter sind die enthaltene Aktivität oder das Fragment und GoogleMapOptions (die null sein können) mit Konfigurationsattributen für MapView erforderlich. Die Basis-Klasse der Aktivität oder Fragmente muss entweder eine FragmentActivity- bzw. eine Support-Fragment sein, da sie Zugriff auf ihren Lebenszyklus bieten.

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

Ein MapView in einem Fragment ist mit dem obigen Beispiel für MapView in einer Aktivität identisch, mit der Ausnahme, dass das Fragment das Layout aufbläht, das MapView in der Fragmentmethode onCreateView() enthält.

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

Kamerazoom für eine Fahrt anpassen

Mit der standardmäßigen Mein Standort-Schaltfläche im Maps SDK wird die Kamera auf den Nutzerstandort zentriert.

Wenn es eine aktive „Journey Sharing“-Sitzung gibt, sollten Sie die Kamera so zentrieren, dass der Fokus auf dem Weg statt auf den Standort des Nutzers liegt.

Consumer-SDK für integrierte Android-Lösung: AutoCamera

Damit Sie sich auf den Weg statt auf den Nutzerstandort konzentrieren können, bietet das Consumer SDK eine AutoCamera-Funktion, die standardmäßig aktiviert ist. Die Kamera zoomt, um die Route für den gemeinsamen Weg und den nächsten Wegpunkt zu sehen.

Autokamera

Kameraverhalten anpassen

Wenn Sie mehr Kontrolle über das Kameraverhalten benötigen, können Sie die Autokamera mit ConsumerController.setAutoCameraEnabled() deaktivieren oder aktivieren.

ConsumerController.getCameraUpdate() gibt die empfohlenen Kameragrenzen zu diesem Zeitpunkt zurück. Sie können dieses CameraUpdate dann als Argument für GoogleMap.moveCamera() oder GoogleMap.animationCamera() angeben.

Auf Mitfahrgelegenheiten und Karten zugreifen

Sie benötigen Zugriff auf ConsumerGoogleMap und ConsumerController, um die gemeinsame Nutzung von Mitfahrgelegenheiten und Karteninteraktionen in Ihrer Anwendung zu unterstützen. ConsumerMapFragment und ConsumerMapView geben beide asynchron ConsumerGoogleMap in ConsumerMapReadyCallback zurück. ConsumerGoogleMap gibt ConsumerController von getConsumerController() zurück. Sie können folgendermaßen auf ConsumerGoogleMap und ConsumerController zugreifen.

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

VerbraucherGoogleMap

ConsumerGoogleMap ist eine Wrapper-Klasse für die Klasse GoogleMap. Ihre App hat die Möglichkeit, über eine API, die GoogleMap entspricht, mit der Karte zu interagieren. Mithilfe der Kundenkarte können Ihre App und Ihre Mitfahrgelegenheit nahtlos mit derselben zugrunde liegenden GoogleMap-Karte interagieren. Beispielsweise erlaubt GoogleMap nur eine einzige Callback-Registrierung, ConsumerGoogleMap unterstützt jedoch zwei registrierte Callbacks. Mit diesen Callbacks können deine App und deine Mitfahrdienst Callbacks registrieren, die nacheinander aufgerufen werden.

ConsumerController

ConsumerController bietet Zugriff auf Mitfahrdienstfunktionen, z. B. zum Beobachten von Fahrten, Steuern des Fahrtstatus und Festlegen von Standorten.

„Teilen von Reisen“ einrichten

Nachdem das Back-End einen Nutzer mit einem Fahrzeug abgeglichen hat, verwenden Sie JourneySharingSession, um die Benutzeroberfläche zum Teilen von Fahrten zu starten. Beim Teilen der Fahrt werden der Standort und die Route des übereinstimmenden Fahrzeugs angezeigt. Nachdem Sie das SDK in Ihrer App implementiert haben, können Sie die Funktion hinzufügen, um Fahrten zu überwachen, auf Updates zu achten und Fehler zu beheben. Bei den folgenden Verfahren wird davon ausgegangen, dass die Back-End-Dienste vorhanden sind und Ihre Dienste für den Abgleich von Nutzern mit Fahrzeugen betriebsbereit sind.

  1. Registrieren Sie einen Listener für ein TripModel-Objekt, um Details zur Fahrt zu erhalten, z. B. die voraussichtliche Ankunftszeit und die Entfernung, die das Fahrzeug vor der Ankunft zurücklegen muss.

    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. Konfigurieren Sie Ihre Fahrt mit 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)
    

Teilen von Reisen beenden

Achten Sie darauf, dass das Teilen von Reisen beendet wird, wenn es nicht mehr benötigt wird, z. B. wenn die Hostaktivität gelöscht wird. Durch Beenden der Freigabe der Route werden auch Netzwerkanfragen an die Fleet Engine gestoppt und Speicherlecks verhindert.

Der folgende Beispielcode zeigt, wie Sie das Teilen von Reisen beenden können.

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

Fahrtfehler beheben

Die Methode onTripRefreshError zeigt Fehler an, die während der Fahrtüberwachung auftreten. Für die Zuordnung von Consumer SDK-Fehlern gelten dieselben HTTP/RPC-Richtlinien wie für die Google Cloud Platform. Häufige Fehler beim Monitoring von Fahrten:

HTTP RPC Beschreibung
400 INVALID_ARGUMENT Der Client hat einen ungültigen Fahrtnamen angegeben. Der Name der Fahrt muss das Format providers/{provider_id}/trips/{trip_id} haben. Die provider_id muss die ID des Cloud-Projekts sein, das dem Dienstanbieter gehört.
401 NICHT AUTHENTIFIZIERT Die Anfrage wurde aufgrund eines ungültigen JWT-Tokens nicht authentifiziert. Dieser Fehler tritt auf, wenn das JWT ohne „tripid“ gekennzeichnet ist oder abgelaufen ist.
403 PERMISSION_DENIED Der Client ist nicht berechtigt. Dieser Fehler tritt auf, wenn das JWT ungültig ist, der Client keine Berechtigung hat oder die API für das Clientprojekt nicht aktiviert ist. Möglicherweise fehlt das JWT-Token oder das Token ist mit einer Fahrt-ID signiert, die nicht mit der angefragten Fahrt-ID übereinstimmt.
429 RESOURCE_EXHAUSTED Das Ressourcenkontingent ist null oder die Trafficrate überschreitet das Limit.
503 NICHT VERFÜGBAR Dienst nicht verfügbar. In der Regel ist der Server ausgefallen.
504 DEADLINE_EXCEEDED Die Frist der Anfrage wurde überschritten. Dies geschieht nur, wenn der Aufrufer eine Frist festlegt, die kürzer ist als die Standardfrist der Methode (d.h., die angeforderte Frist ist für die Verarbeitung der Anfrage durch den Server nicht ausreichend) und die Anfrage wurde nicht innerhalb der Frist abgeschlossen.

Weitere Informationen finden Sie unter Fehlerbehandlung für das Consumer SDK.