Mit dem Consumer SDK können Sie eine einfache Verbraucher-App erstellen und ausführen, die in die Backend-Dienste der On-Demand-Lösung „Rides and Deliveries“ eingebunden ist. Sie können eine App für Fahrten und Bestellfortschritte erstellen, mit der Sie eine aktive Fahrt anzeigen, auf Fahrtaktualisierungen reagieren und Fahrtfehler beheben können.
Da das Consumer SDK eine modulare Architektur hat, können Sie die Teile der API, die Sie für Ihre Anwendung nutzen möchten, verwenden und in Ihre eigenen APIs, die von der Fleet Engine bereitgestellten Back-End-Dienste und zusätzliche APIs der Google Maps Platform einbinden.
Mindestsystemanforderungen
Auf dem Mobilgerät muss Android 6.0 (API-Level 23) oder höher installiert sein.
Build- und Abhängigkeitenkonfiguration
Consumer SDK-Versionen 1.99.0 und höher sind über das Google Maven-Repository verfügbar. Der zuvor verwendete Kanal für private Repositories wurde eingestellt.
Gradle
Füge deiner Datei build.gradle
Folgendes hinzu:
repositories {
...
google()
}
Maven
Füge deiner Datei pom.xml
Folgendes hinzu:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Projektkonfiguration
Wenn du das Consumer SDK for Android verwenden möchtest, muss deine App auf minSdkVersion
23 oder höher ausgerichtet sein.
Zum Ausführen einer App, die mit dem Consumer SDK erstellt wurde, müssen auf dem Android-Gerät Google Play-Dienste installiert sein.
Entwicklungsprojekt einrichten
So richten Sie in der Google Cloud Console Ihr Entwicklungsprojekt ein und rufen einen API-Schlüssel für das Projekt ab:
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 angezeigt wird.
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 > Bibliothek aus, suchen Sie nach dem Maps SDK for Android und aktivieren Sie es.
Rufen Sie einen API-Schlüssel für das Projekt ab. Wählen Sie dazu APIs und Dienste > Anmeldedaten > Anmeldedaten erstellen > API-Schlüssel aus. Weitere Informationen
Consumer SDK zur App hinzufügen
Das Consumer SDK ist über ein privates Maven-Repository verfügbar. Das Repository enthält die Project Object Model-Dateien (pom) des SDK und Javadocs. So fügen Sie Ihrer App das Consumer SDK hinzu:
Richten Sie Ihre Umgebung für den Zugriff auf das Maven-Host-Repository ein, wie im vorherigen Abschnitt beschrieben.
Wenn Sie die zentralisierte Abhängigkeitsverwaltung in
settings.gradle
deklariert haben, deaktivieren Sie sie so.Entferne den folgenden Codeblock in
settings.gradle
:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Fügen Sie Ihrer Gradle- oder Maven-Konfiguration die folgende Abhängigkeit hinzu und ersetzen Sie 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>
Das Consumer SDK hängt vom Maps SDK ab. Diese Abhängigkeit ist so konfiguriert, dass das Consumer SDK weiterhin mit der unterstützten Mindestversion des Maps SDK fortgesetzt wird, wenn die Version des Maps SDK in der Build-Konfigurationsdatei nicht explizit definiert ist (siehe Beispiel unten).
Gradle
Fügen Sie zum
build.gradle
Folgendes hinzu:dependencies { ... implementation 'com.google.android.gms:play-services-maps:18.1.0' }
Maven
Fügen Sie zum
pom.xml
Folgendes hinzu:<dependencies> ... <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-maps</artifactId> <version>18.1.0</version> </dependency> </dependencies>
API-Schlüssel in die App einfügen
Nachdem Sie Ihrer App das Consumer SDK hinzugefügt haben, fügen Sie Ihrer App den API-Schlüssel hinzu. Dazu müssen Sie den Projekt-API-Schlüssel verwenden, den Sie beim Einrichten Ihres Entwicklungsprojekts erhalten haben.
In diesem Abschnitt wird beschrieben, wie Sie Ihren API-Schlüssel speichern, damit er von Ihrer Anwendung sicherer referenziert werden kann. Er sollte nicht in Ihr Versionsverwaltungssystem eingecheckt werden. Sie sollte in der Datei local.properties
gespeichert werden, die sich im Stammverzeichnis Ihres Projekts befindet. Weitere Informationen zur Datei local.properties
finden Sie unter Gradle properties files (nur in englischer Sprache verfügbar).
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:
Öffnen Sie die Datei
build.gradle
auf Stammebene und fügen Sie folgenden Code in dasdependencies
-Element unterbuildscript
ein: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") } }
Öffnen Sie die Datei
build.gradle
auf App-Ebene und fügen Sie den folgenden Code in dasplugins
-Element ein.Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Wenn Sie Android Studio verwenden, synchronisieren Sie Ihr Projekt mit Gradle.
Öffnen Sie die Datei
local.properties
in Ihrem Verzeichnis auf Projektebene und fügen Sie den folgenden Code hinzu. Ersetzen Sie dabeiYOUR_API_KEY
durch Ihren eigenen API-Schlüssel.MAPS_API_KEY=YOUR_API_KEY
Gehen Sie in der Datei
AndroidManifest.xml
zucom.google.android.geo.API_KEY
und aktualisieren Sie das Attributandroid: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 Beispiel-App:
<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>
Nimm die erforderlichen Quellenangaben in deine App auf.
Wenn Sie das Consumer SDK in Ihrer App verwenden, müssen Sie im Abschnitt „Rechtliche Hinweise“ der App Quellenangaben und Open-Source-Lizenzen hinzufügen. Die Quellenangaben sollten am besten als eigenständigen Menüpunkt oder als Teil des Menüpunkts About (Info) eingefügt werden.
Die Lizenzinformationen finden Sie in der Datei „third_party_licenses.txt“ in der nicht archivierten AAR-Datei.
Weitere Informationen zum Einfügen von Open-Source-Hinweisen finden Sie unter https://developers.google.com/android/guides/opensource.
Consumer SDK-Authentifizierung
Das Consumer SDK bietet eine Authentifizierung mithilfe von JSON-Webtokens. Ein JSON Web Token (JWT) ist ein JSON-basiertes Zugriffstoken, das eine oder mehrere Anforderungen für einen Dienst bereitstellt. Beispielsweise könnte ein Server ein Token mit der Anforderung „als Administrator angemeldet“ generieren und einem Client zur Verfügung stellen. 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 muss im authorization
-Header des Tokens die Anforderung tripid:TRIP_ID
enthalten, wobei TRIP_ID
die Fahrt-ID ist. Dadurch erhält das Consumer SDK Zugriff auf Fahrtdetails wie Fahrzeugposition, Route und voraussichtliche Ankunftszeit.
JSON Web Token-Callbacks
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 zu erhalten, die eine Autorisierung erfordern.
Wir empfehlen dringend, dass Ihre Callback-Implementierung Autorisierungstokens im Cache speichert und erst nach Ablauf der expiry
-Zeit aktualisiert. Tokens laufen in der Regel nach einer Stunde ab.
Der Callback für das Autorisierungstoken gibt an, welches Diensttoken für den TripService
-Dienst erforderlich ist. Außerdem wird das erforderliche tripId
für den Kontext angegeben.
Das folgende Codebeispiel zeigt, wie ein Autorisierungstoken-Callback implementiert wird.
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
Bevor Sie diese Verfahren ausführen, wird davon ausgegangen, dass Sie die entsprechenden Dienste und das Consumer SDK aktiviert haben.
ConsumerApi
-Instanz abrufen
Damit du das Consumer SDK verwenden kannst, muss deine App ConsumerApi
asynchron initialisieren. Die API ist ein Singleton-Element.
Die Initialisierungsmethode verwendet einen AuthTokenFactory
. Die Factory generiert bei Bedarf neue JWT-Tokens für den Nutzer.
Die providerId
ist die Projekt-ID Ihres Google Cloud-Projekts. Weitere Informationen zum Erstellen des Projekts finden Sie im Fleet Engine-Nutzerhandbuch.
Deine App sollte die AuthTokenFactory
wie unter Consumer SDK-Authentifizierung beschrieben implementieren.
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
}
Maps SDK und Karten-Renderer
Version 2.x.x des Consumer SDK unterstützt das Maps SDK for Android ab Version 18.1.0. In der folgenden Tabelle sind der Standard-Renderer nach Maps SDK-Version und die Unterstützung beider Renderer zusammengefasst. Wir empfehlen die Verwendung des neuesten Renderers. Wenn Sie jedoch den alten Renderer verwenden müssen, können Sie ihn explizit mit MapsInitializer.initialize()
angeben.
Maps SDK-Version | Unterstützt den neuesten Renderer | Unterstützt den alten Renderer | Standard-Renderer |
---|---|---|---|
V18.1.0 und niedriger | Ja | Ja | Alt* |
V18.2.0 | Ja | Ja | Neueste |
* Mit der Einführung des neuen Maps-Renderers ist der Renderer „Neueste“ standardmäßig verwendet.
Maps SDK als Abhängigkeit hinzufügen
Gradle
Fügen Sie zum build.gradle
Folgendes hinzu:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:VERSION_NUMBER"
}
Maven
Fügen Sie zum pom.xml
Folgendes hinzu:
<dependencies>
...
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>18.1.0</version>
</dependency>
</dependencies>
Maps SDK vor der Initialisierung des Consumer SDK initialisieren
Rufen Sie in der Application
- oder Start-Activity
-Klasse MapsInitializer.initialize() auf und warten Sie auf das Ergebnis der Renderer-Anfrage, bevor Sie das Consumer SDK initialisieren.
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()
}
})
}
Benutzeroberfläche erstellen
Sie können entweder ConsumerMapFragment
oder ConsumerMapView
verwenden, um die Benutzeroberfläche für Ihre Anwendung zu erstellen. Mit ConsumerMapFragment
können Sie Ihre Karte mithilfe eines Fragment
definieren, während Sie mit ConsumerMapView
ein View
-Element verwenden können. Die Funktionen für Mitfahrdienste sind in ConsumerMapView
und ConsumerMapFragment
identisch. Sie können also eine Option auswählen, je nachdem, ob View
oder Fragment
für Ihre App 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 erfordert, füge deiner Aktivität den folgenden Code hinzu. Dieser Code erweitert AppCompatActivity
um die Verwendung der Vektor-Drawables im Consumer SDK.
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 Journey-Teilen entweder in einem Android-Fragment oder in einer Ansicht, die Sie in der XML-Datei für das Anwendungslayout (/res/layout
) definieren. Das Fragment (oder die Ansicht) bietet dann Zugriff auf die Journey Map, auf die Ihre App zugreifen und diese ändern kann. Die Karte enthält auch einen Handle für ConsumerController
, mit dem deine App das Teilen von Fahrten steuern und anpassen kann.
Karte und Controller teilen
Die Journey Map wird entweder als Fragment (mit ConsumerMapFragment
) oder als Ansicht (mit ConsumerMapView
) definiert, wie im folgenden Codebeispiel gezeigt. Die Methode onCreate()
sollte dann getConsumerGoogleMapAsync(callback)
aufrufen, das ConsumerGoogleMap
im Callback asynchron zurückgibt. Anschließend verwenden Sie ConsumerGoogleMap
, um die Reise teilen zu können, und diese kann nach Bedarf von Ihrer App aktualisiert werden.
ConsumerMapFragment
Das Fragment wird in der XML-Datei für das Anwendungslayout definiert, wie im folgenden Codebeispiel veranschaulicht.
<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 über die Methode onCreate()
erfolgen.
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
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()
muss von onCreate()
stammen. Zusätzlich zum Callback-Parameter sind die enthaltende Aktivität oder das Fragment sowie GoogleMapOptions
(kann null) enthalten und Konfigurationsattribute für MapView
enthalten. Die Basisklasse der Aktivität oder des Fragments muss entweder ein FragmentActivity
- oder ein Support-Fragment
sein, da sie Zugriff auf seinen 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 entspricht dem obigen Beispiel für MapView
in einer Aktivität, mit der Ausnahme, dass das Fragment das Layout erhöht, das MapView
in der Fragment-Methode 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 wird angepasst, um den Fokus auf eine Fahrt zu lenken
Über die standardmäßig im Maps SDK integrierte Schaltfläche „Mein Standort“ wird die Kamera auf den Gerätestandort zentriert.
Wenn eine aktive Sitzung mit dem Teilen von Reisen vorhanden ist, kann es sinnvoll sein, die Kamera mittig auf die Fahrt statt auf den Gerätestandort zu fokussieren.
Integrierte Lösung für das Consumer SDK for Android: AutoCamera
Damit Sie sich auf die Reise statt auf den Gerätestandort konzentrieren können, bietet das Consumer SDK eine standardmäßig aktivierte AutoCamera-Funktion. Die Kamera zoomt, um die gemeinsame Route und den nächsten Wegpunkt zu fokussieren.
Kameraverhalten anpassen
Wenn Sie mehr Kontrolle über das Kameraverhalten benötigen, können Sie die automatische Kamera mithilfe von ConsumerController.setAutoCameraEnabled() deaktivieren oder aktivieren.
ConsumerController.getCameraUpdate() gibt die derzeit empfohlenen Kameragrenzen zurück. Anschließend können Sie dieses CameraUpdate
als Argument für GoogleMap.moveCamera() oder GoogleMap.animateCamera() angeben.
Auf Mitfahrgelegenheiten und Karten zugreifen
Damit Sie Mitfahrgelegenheiten und die Interaktion mit Karten in Ihrer App unterstützen können, benötigen Sie Zugriff auf ConsumerGoogleMap
und ConsumerController
.
ConsumerMapFragment
und ConsumerMapView
geben beide asynchron ConsumerGoogleMap
in ConsumerMapReadyCallback
zurück.
ConsumerGoogleMap
gibt ConsumerController
von getConsumerController()
zurück. So können Sie 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,
}
)
ConsumerGoogleMap
ConsumerGoogleMap
ist eine Wrapper-Klasse für die GoogleMap
-Klasse. Damit kann Ihre App über eine API, die GoogleMap
entspricht, mit der Karte interagieren. Mithilfe der Karte für Nutzer können Ihre App und Ihr Mitfahrdienst nahtlos mit demselben zugrunde liegenden GoogleMap-Objekt interagieren. Beispielsweise lässt GoogleMap
nur eine einzelne Callback-Registrierung zu, ConsumerGoogleMap
unterstützt aber doppelt registrierte Callbacks.
Mit diesen Callbacks können deine App und dein Mitfahrdienst Callbacks registrieren, die nacheinander aufgerufen werden.
ConsumerController
ConsumerController
bietet Zugriff auf Funktionen zur gemeinsamen Nutzung von Mitfahrgelegenheiten, z. B. zur Fahrtenüberwachung, zur Steuerung des Fahrtstatus und zum Festlegen von Orten.
Teilen von Reisen einrichten
Nachdem das Back-End einen Nutzer einem Fahrzeug zugeordnet hat, verwenden Sie JourneySharingSession
, um die Benutzeroberfläche zum Teilen der Journey zu starten. Bei der Routenfreigabe werden der entsprechende
Fahrzeugstandort und die Route angezeigt. Nachdem du das SDK in deiner App implementiert hast, kannst du die Funktionen für die Fahrtüberwachung, das Warten auf Updates und die Fehlerbehebung hinzufügen.
Bei den folgenden Verfahren wird davon ausgegangen, dass die Back-End-Dienste vorhanden sind und Ihre Dienste zum Abgleich von Nutzern mit Fahrzeugen betriebsbereit sind.
Registrieren Sie einen Listener für ein
TripModel
-Objekt, um Details zur Fahrt abzurufen, z. B. die voraussichtliche Ankunftszeit (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?, ) { // ... } // ... })
Konfiguriere deine 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 der Route beenden
Beenden Sie die Journey-Freigabe, wenn sie nicht mehr benötigt wird, z. B. wenn die Hostaktivität gelöscht wird. Wenn Sie die Fahrtfreigabe beenden, werden auch Netzwerkanfragen an Fleet Engine gestoppt und Speicherlecks vermieden.
Im folgenden Beispielcode sehen Sie, wie Sie die Freigabe von Journeys beenden.
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()
}
}
Mit Fahrtfehlern umgehen
Die Methode onTripRefreshError
zeigt Fehler an, die während der Fahrtüberwachung auftreten.
Die Zuordnung von Consumer SDK-Fehlern erfolgt gemäß den HTTP/RPC-Richtlinien für die Google Cloud Platform.
Häufige Fehler bei der Fahrtüberwachung sind:
HTTP | RPC | Beschreibung |
---|---|---|
400 | INVALID_ARGUMENT | Der Kunde 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-Token ohne Fahrt-ID signiert wird oder das JWT-Token abgelaufen ist. |
403 | PERMISSION_DENIED | Der Client hat nicht die erforderlichen Berechtigungen. Dieser Fehler tritt auf, wenn das JWT-Token ungültig ist, der Client keine Berechtigung hat oder die API nicht für das Clientprojekt aktiviert ist. Möglicherweise fehlt das JWT-Token oder es ist mit einer Fahrt-ID signiert, die nicht mit der angeforderten Fahrt-ID übereinstimmt. |
429 | RESOURCE_EXHAUSTED | Das Ressourcenkontingent beträgt null oder die Traffic-Rate überschreitet das Limit. |
503 | UNAVAILABLE | Dienst nicht verfügbar: Normalerweise 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 als die Standardfrist der Methode ist (d.h. die angeforderte Frist reicht nicht aus, damit der Server die Anfrage verarbeitet) und die Anfrage nicht innerhalb der Frist abgeschlossen wurde. |
Weitere Informationen findest du unter Fehlerbehandlung im Consumer SDK.