Za pomocą pakietu Consumer SDK możesz utworzyć i uruchomić podstawową aplikację zintegrowaną z usługami backendu przejazdów i rozwiązań dostarczanych na żądanie. Możesz utworzyć aplikacje Podróż i Postępy zamówienia, które będą mogły wyświetlać aktywną podróż, odpowiadać na jej aktualizacje i naprawiać błędy.
Pakiet Consumer SDK ma architekturę modułową, dzięki czemu możesz używać części interfejsu API, których chcesz używać w konkretnej aplikacji, oraz integrować je z własnymi interfejsami API, usługami backendu udostępnianymi przez Fleet Engine i dodatkowymi interfejsami API Google Maps Platform.
Minimalne wymagania systemowe
Na urządzeniu mobilnym musi być zainstalowany Android 6.0 (poziom interfejsu API 23) lub nowszy.
Konfiguracja Maven
Pakiet Consumer SDK w wersji 1.99.0 i nowszych jest dostępny w repozytorium Google Maven.
Gradle
Dodaj do pliku build.gradle
te informacje:
repositories {
...
google()
}
Maven
Dodaj do pliku pom.xml
te informacje:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Konfiguracja projektu
Aby można było używać pakietu Consumer SDK na Androida, Twoja aplikacja musi być kierowana na minSdkVersion
w wersji 23 lub nowszej.
Aby uruchomić aplikację utworzoną za pomocą pakietu Consumer SDK, na urządzeniu z Androidem muszą być zainstalowane Usługi Google Play.
Konfigurowanie projektu programistycznego
Aby skonfigurować projekt programistyczny i uzyskać jego klucz interfejsu API w konsoli Google Cloud:
Utwórz nowy projekt Google Cloud Console lub wybierz istniejący projekt do użycia z pakietem Consumer SDK. Zaczekaj kilka minut, aż nowy projekt pojawi się w konsoli Google Cloud.
Aby uruchomić aplikację demonstracyjną, projekt musi mieć dostęp do pakietu Maps SDK na Androida. W konsoli Google Cloud wybierz Interfejsy API i usługi > Biblioteka, a następnie wyszukaj i włącz pakiet SDK Map Google na Androida.
Aby uzyskać klucz interfejsu API projektu, wybierz Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz interfejsu API. Więcej informacji o uzyskiwaniu klucza interfejsu API znajdziesz w artykule Uzyskiwanie klucza interfejsu API.
Dodawanie do aplikacji pakietu Consumer SDK
Pakiet Consumer SDK jest dostępny w prywatnym repozytorium Maven. Repozytorium zawiera pliki modelu obiektu projektu (.pom) z pakietu SDK i dokumenty Javadocs. Aby dodać do aplikacji pakiet SDK Consumer SDK:
Skonfiguruj środowisko tak, aby uzyskać dostęp do repozytorium Maven hosta zgodnie z opisem w poprzedniej sekcji.
Jeśli masz zadeklarowaną w
settings.gradle
scentralizowaną konfigurację zarządzania zależnościami, wyłącz ją w ten sposób.Usuń ten blok kodu z pliku
settings.gradle
:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Dodaj zależność do konfiguracji Gradle lub Maven, zastępując zmienną
VERSION_NUMBER
odpowiednią wersją pakietu Consumer SDK.Gradle
Dodaj do konta
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Maven
Dodaj do konta
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Dodawanie klucza interfejsu API do aplikacji
Po dodaniu pakietu SDK dla konsumentów do aplikacji dodaj do niej klucz interfejsu API. Musisz użyć klucza interfejsu API projektu uzyskanego podczas konfigurowania projektu programistycznego.
Z tej sekcji dowiesz się, jak przechowywać klucz interfejsu API, aby można było bezpieczniej się do niego odwoływać w aplikacji. Nie sprawdzaj klucza interfejsu API w systemie kontroli wersji. Powinien znajdować się w pliku local.properties
, który znajduje się w katalogu głównym projektu. Więcej informacji o pliku local.properties
znajdziesz w artykule Pliki właściwości Gradle.
Aby ułatwić sobie to zadanie, możesz użyć wtyczki do obsługi obiektów tajnych w Gradle na Androida.
Aby zainstalować wtyczkę i zapisać klucz interfejsu API:
Otwórz plik
build.gradle
głównego poziomu i dodaj ten kod do elementudependencies
w obszarzebuildscript
.Zakręcony
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") } }
Otwórz plik
build.gradle
na poziomie aplikacji i dodaj do elementuplugins
podany niżej kod.Zakręcony
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Jeśli używasz Android Studio, zsynchronizuj projekt z Gradle.
Otwórz
local.properties
w katalogu na poziomie projektu, a następnie dodaj ten kod. ZastąpYOUR_API_KEY
swoim kluczem interfejsu API.MAPS_API_KEY=YOUR_API_KEY
W pliku
AndroidManifest.xml
przejdź docom.google.android.geo.API_KEY
i zaktualizuj atrybutandroid:value
w ten sposób:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
Ten przykład przedstawia pełny plik manifestu przykładowej aplikacji:
<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>
Uwzględnij wymagane informacje o atrybucji w aplikacji
Jeśli korzystasz w aplikacji z pakietu SDK dla konsumentów, w sekcji informacji prawnych dotyczących aplikacji musisz umieścić tekst źródła oraz licencje open source. Informacje o autorach najlepiej dodać jako niezależne pozycje w menu lub pozycję Informacje.
Wymagany tekst źródła i licencje open source znajdziesz w pliku ZIP z Ridesharing Consumer SDK:
NOTICE.txt
LICENSES.txt
Uwierzytelnianie pakietu Consumer SDK
Pakiet SDK Consumer SDK zapewnia uwierzytelnianie za pomocą tokenów sieciowych JSON. Token internetowy JSON (JWT) to token dostępu w bazie danych JSON, który udostępnia co najmniej 1 deklarację w usłudze. Serwer może na przykład wygenerować token z deklaracją „zalogowany jako administrator” i przekazać go klientowi. Może on następnie użyć tego tokena, aby udowodnić, że jest zalogowany jako administrator.
Pakiet Consumer SDK komunikuje się z Fleet Engine za pomocą tokena internetowego JSON udostępnionego przez aplikację. Więcej informacji znajdziesz w artykule Uwierzytelnianie i autoryzacja Fleet Engine.
Token autoryzacji zapewnia dostęp do tych usługFleet Engine:
TripService
– daje pakietowi SDK konsumentów dostęp do szczegółów podróży, w tym do pozycji pojazdu, trasy i szacowanego czasu dotarcia. Tokeny autoryzacji dla usługi podróży muszą zawierać żądanietripid:TRIP_ID
w nagłówkuauthorization
tokena, gdzieTRIP_ID
to identyfikator podróży.VehicleService
– przekazuje pakietowi SDK dla konsumentów informacje o niewyraźnym lokalizacji pojazdu na potrzeby wyświetlania warstwy gęstości pojazdów i szacowania szacowanego czasu dotarcia na miejsce w punkcie odbioru. Pakiet SDK dla konsumentów używa tylko lokalizacji zamazanych, dlatego tokeny autoryzacji usługi pojazdu nie wymagają żądaniavehicleid
.
Wywołania zwrotne tokena internetowego JSON
Podczas inicjowania pakiet SDK Consumer SDK rejestruje wywołanie zwrotne tokena autoryzacji w aplikacji. SDK wywołuje aplikację, aby uzyskać token dla wszystkich żądań sieciowych, które wymagają autoryzacji.
Zdecydowanie zalecamy, aby tokeny autoryzacji bufora w implementacji wywołania zwrotnego były przechowywane w pamięci podręcznej i odświeżały je dopiero po upływie czasu expiry
. Tokeny powinny być wydawane z datą ważności wynoszącą godzinę.
Wywołanie zwrotne tokena autoryzacji określa, który token usługi jest wymagany przez usługę TripService
. Dostarcza też element tripId
wymagany w tym kontekście.
Poniższy przykładowy kod pokazuje, jak wdrożyć wywołanie zwrotne tokena autoryzacji.
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
}
}
}
Inicjowanie interfejsu API
Przed wykonaniem tych procedur zakładamy, że masz włączone odpowiednie usługi i pakiet Consumer SDK.
Pobieranie instancji ConsumerApi
Aby można było używać pakietu Consumer SDK, aplikacja musi zainicjować ConsumerApi
asynchronicznie. Interfejs API jest typu singleton.
Metoda inicjowania wymaga metody AuthTokenFactory
. W razie potrzeby fabryka generuje nowe tokeny JWT dla użytkownika.
providerId
to identyfikator projektu Google Cloud. Więcej informacji o tworzeniu projektu znajdziesz w przewodniku użytkownika Fleet Engine.
Aplikacja powinna implementować AuthTokenFactory
w sposób opisany w artykule Uwierzytelnianie SDK klienta.
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
}
Zainicjuj pakiet SDK Map Google, aby zażądać preferowanego mechanizmu renderowania
Pakiet SDK dla klientów indywidualnych w wersji 2.0.0 obsługuje pakiet SDK Map Google na Androida w wersji 18.1.0 i nowszych. Obsługuje żądania z określonym preferowanym mechanizmem renderowania Map Google. Szczegółowe informacje znajdziesz w sekcji Nowy mechanizm renderowania map(włącz).
Dodaj pakiet SDK Map Google jako zależność
Gradle
Dodaj do konta build.gradle
:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:18.1.0"
}
Maven
Dodaj do konta pom.xml
:
<dependencies>
...
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>18.1.0</version>
</dependency>
</dependencies>
Zainicjuj pakiet SDK Map Google przed zainicjowaniem pakietu Consumer SDK
W klasie Application
lub uruchamiającej Activity
wywołaj metodę mapsInitializer.initialize() i poczekaj na wynik żądania mechanizmu renderowania, zanim zainicjujesz pakiet SDK klienta.
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()
}
})
}
Tworzenie interfejsu użytkownika
Interfejs aplikacji możesz utworzyć, korzystając z ConsumerMapFragment
lub ConsumerMapView
. ConsumerMapFragment
pozwala zdefiniować mapę za pomocą Fragment
, a ConsumerMapView
– View
. Funkcje wspólnych przejazdów są takie same w ConsumerMapView
i ConsumerMapFragment
, więc możesz wybrać tę, która lepiej odpowiada Twojej aplikacji View
lub Fragment
.
Dodano obsługę interfejsu API 19 (KitKat) i elementów rysowalnych wektorowych
Jeśli projekt Twojej aplikacji wymaga obsługi urządzeń z interfejsem API 19 (KitKat) i elementów rysowanych wektorowych, dodaj do aktywności poniższy kod. Ten kod rozszerza zakres AppCompatActivity
o elementy rysowane wektorowe w pakiecie Consumer SDK.
Java
// ...
import android.support.v7.app.AppCompatActivity;
// ...
public class ConsumerTestActivity extends AppCompatActivity {
// ...
}
Kotlin
// ...
import android.support.v7.app.AppCompatActivity
// ...
class ConsumerTestActivity : AppCompatActivity() {
// ...
}
Dodawanie fragmentu lub widoku mapy
Mapę do wyświetlania udostępniania podróży tworzysz we fragmencie Androida lub widoku, który definiujesz w pliku XML układu aplikacji (znajdującym się w lokalizacji /res/layout
). Fragment (lub widok) umożliwia dostęp do mapy udostępniania przejazdu, którą aplikacja może otwierać i modyfikować. Mapa zawiera też uchwyt ConsumerController
, dzięki któremu aplikacja może kontrolować i dostosowywać udostępnianie trasy.
Udostępnianie mapy i kontrolera podczas podróży
Mapę udostępniania przejazdu definiujesz jako fragment (za pomocą ConsumerMapFragment
) lub jako widok (za pomocą ConsumerMapView
), jak w tym przykładzie kodu. Twoja metoda onCreate()
powinna następnie wywołać metodę getConsumerGoogleMapAsync(callback)
, która asynchronicznie zwraca ConsumerGoogleMap
w wywołaniu zwrotnym. Następnie możesz używać ConsumerGoogleMap
do wyświetlania informacji o udostępnianiu trasy. Aplikacja może go aktualizować.
ConsumerMapFragment
Fragment definiujesz w pliku XML układu aplikacji, jak pokazano w poniższym przykładzie kodu.
<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" />
Wywołanie getConsumerGoogleMapAsync()
powinno pochodzić z metody 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()!!
}
}
)
}
}
Widok mapy klienta
Widok można wykorzystać we fragmencie lub aktywności, zgodnie z definicją w pliku 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" />
Połączenie z numerem getConsumerGoogleMapAsync()
powinno pochodzić od: onCreate()
. Oprócz parametru wywołania zwrotnego wymaga on działania lub fragmentu zawierającego ciąg oraz parametru GoogleMapOptions
(który może mieć wartość null) zawierającego atrybuty konfiguracji dla MapView
. Klasa bazowa działania lub fragmentu musi mieć typ FragmentActivity
lub pomocniczą Fragment
, ponieważ zapewnia dostęp do jej cyklu życia.
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,
)
}
}
Element MapView
we fragmencie jest taki sam jak w przykładzie powyżej w przypadku elementu MapView
w aktywności. Jedyna różnica jest taka, że fragment rozszerza układ, który obejmuje metodę MapView
we fragmencie 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)
}
}
Dostosowanie powiększenia aparatu, aby skupić się na podróży
Domyślny przycisk Moja lokalizacja wbudowany w pakiet SDK Map Google ustawia kamerę zgodnie z lokalizacją urządzenia.
Jeśli masz aktywną sesję udostępniania trasy, wyśrodkuj kamerę, aby skupić się na podróży, a nie na lokalizacji urządzenia.
Wbudowane rozwiązanie pakietu SDK dla klientów indywidualnych na Androida: Autokamera
Aby umożliwić Ci skupienie się na podróży, a nie na lokalizacji urządzenia, pakiet SDK klienta zapewnia funkcję automatycznego aparatu, która jest domyślnie włączona. Kamera powiększa obraz, żeby skupić się na udostępnianiu trasy i następnym punkcie na trasie.
Dostosowywanie działania kamery
Jeśli chcesz mieć większą kontrolę nad działaniem kamery, możesz wyłączyć lub włączyć kamerę automatyczną za pomocą metody ConsumerController.setAutoCameraEnabled().
ConsumerController.getCameraUpdate() zwraca zalecane granice kamery w danym momencie. Następnie możesz podać ten argument CameraUpdate
jako argument funkcji GoogleMap.moveCamera() lub GoogleMap.animateCamera().
Korzystaj ze wspólnych przejazdów i map
Aby obsługiwać wspólne przejazdy i interakcję z mapami w aplikacji, musisz mieć dostęp do ConsumerGoogleMap
i ConsumerController
.
Funkcje ConsumerMapFragment
i ConsumerMapView
asynchronicznie zwracają wartość ConsumerGoogleMap
w parametrze ConsumerMapReadyCallback
.
ConsumerGoogleMap
zwraca ConsumerController
od getConsumerController()
. Dostęp do ConsumerGoogleMap
i ConsumerController
możesz uzyskać w ten sposób.
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,
}
)
MapaGoogle dla klientów
ConsumerGoogleMap
to klasa opakowująca klasy GoogleMap
. Umożliwia aplikacji interakcję z mapą za pomocą interfejsu API równoważnego z GoogleMap
. Korzystanie z mapy klientów umożliwia bezproblemową interakcję aplikacji i przejazdów z tą samą bazową Mapą Google. Na przykład GoogleMap
zezwala na tylko 1 rejestrację wywołania zwrotnego, ale ConsumerGoogleMap
obsługuje podwójne zarejestrowane wywołania zwrotne.
Dzięki tym wywołaniam zwrotnym aplikacja i udostępnianie przejazdów mogą rejestrować wywołania zwrotne, które są wywoływane sekwencyjnie.
Kontrola klienta
ConsumerController
zapewnia dostęp do funkcji wspólnych przejazdów, takich jak monitorowanie podróży, kontrolowanie jej stanu i ustawianie lokalizacji.
Skonfiguruj udostępnianie przejazdów
Gdy backend dopasuje klienta do pojazdu, użyj JourneySharingSession
, aby uruchomić interfejs udostępniania podróży. Udostępnianie trasy dojazdu pokazuje
dopasowaną lokalizację pojazdu i trasę. Po zaimplementowaniu pakietu SDK w aplikacji możesz dodać funkcję monitorowania podróży, nasłuchiwania aktualizacji i obsługi błędów.
W poniższych procedurach założono, że usługi backendu są dostępne i że usługi dopasowywania konsumenta do pojazdów działają.
Zarejestruj detektor na obiekcie
TripModel
, aby otrzymywać szczegółowe informacje o podróży, takie jak szacowany czas przyjazdu i odległość, jaką musi pokonać pojazd przed przyjazdem.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?, ) { // ... } // ... })
Skonfiguruj podróż za pomocą
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)
Przestań udostępniać trasę
Zatrzymuj udostępnianie przejazdów, gdy nie jest już potrzebne, na przykład po zniszczeniu aktywności hosta. Zatrzymanie udostępniania ścieżki zatrzymuje też żądania sieciowe wysyłane do Fleet Engine i zapobiega wyciekom pamięci.
Poniższy przykładowy kod pokazuje, jak zatrzymać udostępnianie przejazdów.
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()
}
}
Obsługa błędów w podróży
Metoda onTripRefreshError
wyświetla błędy, które występują podczas monitorowania podróży.
Mapowanie błędów w pakiecie Consumer SDK jest zgodne z wytycznymi dotyczącymi protokołu HTTP/RPC obowiązującymi w przypadku Google Cloud Platform.
Do częstych błędów zgłaszanych podczas monitorowania podróży należą:
HTTP | RPC | Opis |
---|---|---|
400 | NIEPRAWIDŁOWY_ARG | Klient podał nieprawidłową nazwę podróży. Nazwa podróży musi mieć format providers/{provider_id}/trips/{trip_id} .
Parametr provider_id musi być identyfikatorem projektu w chmurze należącego do dostawcy usług. |
401 | NIE UWIERZYTELNIOWA | Żądanie nie zostało uwierzytelnione z powodu nieprawidłowego tokena JWT. Ten błąd występuje, jeśli token JWT jest podpisany bez identyfikatora podróży lub token JWT wygasł. |
403 | UPRAWNIENIA_ODRZUCONO | Klient nie ma wystarczających uprawnień. Ten błąd występuje, jeśli token JWT jest nieprawidłowy, klient nie ma uprawnień lub interfejs API nie jest włączony w projekcie klienta. Być może brakuje tokena JWT lub jest on podpisany identyfikatorem podróży, który nie pasuje do żądanego identyfikatora podróży. |
429 | MATERIAŁY WYKRYWANE | Limit zasobów wynosi zero lub tempo ruchu przekracza limit. |
503 | PRODUKT NIEDOSTĘPNY | Usługa niedostępna Zazwyczaj serwer nie działa. |
504 | PRZEKROCZONO_TERMIN | Przekroczono limit czasu żądania. Dzieje się tak tylko wtedy, gdy wywołujący ustawi termin krótszy niż domyślny termin w przypadku metody (tj. żądany termin nie wystarcza, aby serwer mógł przetworzyć żądanie), a żądanie nie zostało zrealizowane w wyznaczonym terminie. |
Więcej informacji znajdziesz w sekcji Obsługa błędów pakietu SDK klienta.