Za pomocą pakietu SDK dla klientów indywidualnych możesz utworzyć i uruchomić podstawową aplikację dla użytkowników indywidualnych zintegrowaną z usługami backendu rozwiązania w zakresie usług przejazdów na żądanie i dostarczania. Możesz utworzyć aplikację Podróż i Postęp przetwarzania zamówienia, która może wyświetlać aktywną podróż, odpowiadać na aktualizacje podróży i obsługiwać związane z nią błędy.
Pakiet Consumer SDK ma architekturę modułową, dlatego możesz używać części interfejsu API, których chcesz używać w konkretnej aplikacji, i 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 kompilacji i zależności
W repozytorium Google Maven jest dostępny pakiet SDK dla klientów indywidualnych w wersji 1.99.0 lub nowszej. Używany wcześniej kanał repozytorium prywatnego został wycofany.
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 SDK Consumer SDK na Androida, aplikacja musi być kierowana na system minSdkVersion
w wersji 23 lub nowszej.
Aby uruchomić aplikację stworzoną przy użyciu pakietu SDK dla klientów indywidualnych, na urządzeniu z Androidem muszą być zainstalowane Usługi Google Play.
Konfigurowanie projektu programistycznego
Aby skonfigurować projekt programistyczny i uzyskać dla niego klucz interfejsu API w konsoli Google Cloud:
Utwórz nowy projekt konsoli Google Cloud lub wybierz istniejący projekt do użycia z pakietem SDK dla klientów indywidualnych. Zaczekaj kilka minut, aż nowy projekt pojawi się w konsoli Google Cloud.
Aby uruchomić aplikację w wersji demonstracyjnej, Twój 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 Maps SDK na Androida.
Aby uzyskać klucz interfejsu API dla projektu, kliknij Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz interfejsu API. Jeśli chcesz dowiedzieć się, jak uzyskać klucz interfejsu API, przeczytaj, jak uzyskać klucz interfejsu API.
Dodaj do aplikacji pakiet SDK dla klientów indywidualnych
Pakiet SDK dla klientów indywidualnych jest dostępny w prywatnym repozytorium Maven. Repozytorium zawiera pliki modelu obiektu pakietu SDK (.pom) i dokumenty Javadocs. Aby dodać do aplikacji pakiet SDK dla konsumentów:
Skonfiguruj środowisko, aby uzyskać dostęp do hosta Maven w sposób opisany w poprzedniej sekcji.
Jeśli w
settings.gradle
masz zadeklarowaną scentralizowaną konfigurację zarządzania zależnościami, wyłącz ją w następujący sposób.Usuń w
settings.gradle
ten blok kodu:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Dodaj poniższą zależność do konfiguracji Gradle lub Maven, zastępując zmienną
VERSION_NUMBER
odpowiednią wersją pakietu Consumer SDK.Gradle
Dodaj do
build.gradle
:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Maven
Dodaj do
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Pakiet SDK dla klientów indywidualnych korzysta z pakietu Maps SDK. Zależność ta jest skonfigurowana w taki sposób, że jeśli wersja pakietu Maps SDK nie jest wyraźnie określona w pliku konfiguracji kompilacji (tak jak poniżej), to po opublikowaniu nowej wersji pakietu Maps SDK pakiet Consumer SDK będzie nadal korzystać z minimalnej wymaganej wersji pakietu Maps SDK.
Gradle
Dodaj do
build.gradle
:dependencies { ... implementation 'com.google.android.gms:play-services-maps:18.1.0' }
Maven
Dodaj do
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-maps</artifactId> <version>18.1.0</version> </dependency> </dependencies>
Dodawanie klucza interfejsu API do aplikacji
Po dodaniu do aplikacji pakietu Consumer SDK dodaj do niej klucz interfejsu API. Musisz użyć klucza interfejsu API projektu uzyskanego podczas konfigurowania projektu programistycznego.
W tej sekcji dowiesz się, jak przechowywać klucz interfejsu API, aby aplikacja mogła lepiej się do niego odwoływać. Nie należy sprawdzać klucza interfejsu API w systemie kontroli wersji. Powinien on być przechowywany w pliku local.properties
, który znajduje się w katalogu głównym projektu. Więcej informacji o pliku local.properties
znajdziesz w artykule o plikach właściwości Gradle.
Aby usprawnić to zadanie, możesz użyć wtyczki do Gradle obiektów tajnych dla Androida.
Aby zainstalować wtyczkę i zapisać klucz interfejsu API:
Otwórz plik
build.gradle
poziomu głównego i dodaj poniższy kod do elementudependencies
wbuildscript
.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 poniższy kod do elementuplugins
.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 Androida 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ź do miejscacom.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 zawiera 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>
Umieść w aplikacji wymagane informacje o źródłach
Jeśli w swojej aplikacji używasz pakietu SDK dla klientów indywidualnych, w sekcji Informacje prawne o aplikacji musisz umieścić tekst atrybucji i licencje open source. Informacje o źródłach najlepiej dodawać jako niezależną pozycję menu lub jako część pozycji Informacje.
Informacje o licencjach znajdziesz w pliku „third_party_licenses.txt” w przywróconym pliku AAR.
Informacje o tym, jak dołączać powiadomienia o oprogramowaniu open source, znajdziesz na https://developers.google.com/android/guides/opensource.
Uwierzytelnianie za pomocą pakietu SDK klienta
Pakiet SDK Consumer SDK umożliwia uwierzytelnianie za pomocą tokenów sieciowych JSON. Token internetowy JSON (JWT) to podstawowy token dostępu JSON, który udostępnia co najmniej 1 deklarację dotyczącą usługi. Serwer może na przykład wygenerować token z deklaracją „zalogował się jako administrator” i przekazać go klientowi. Za pomocą tego tokena klient może potwierdzić, że jest zalogowany jako administrator.
Pakiet SDK dla klientów indywidualnych używa do komunikacji z flotą silnika internetowego tokena internetowego JSON udostępnionego przez aplikację. Więcej informacji znajdziesz w artykule Uwierzytelnianie i autoryzacja Fleet Engine.
Token autoryzacji musi zawierać deklarację tripid:TRIP_ID
w nagłówku authorization
tokena, gdzie TRIP_ID
to identyfikator podróży. Daje to pakietowi SDK klienta dostęp do szczegółów podróży, takich jak pozycja pojazdu, trasa i szacowany czas dotarcia.
Wywołania zwrotne tokena internetowego JSON
Pakiet SDK klienta rejestruje wywołanie zwrotne tokena autoryzacji w aplikacji podczas inicjowania. Pakiet SDK wywołuje aplikację, aby uzyskać token dla wszystkich żądań sieciowych, które wymagają autoryzacji.
Zdecydowanie zalecamy, aby tokeny autoryzacji pamięci podręcznej implementacji wywołania zwrotnego były odświeżane tylko po upływie czasu expiry
. Tokeny powinny być wydawane z godzinną datą ważności.
Wywołanie zwrotne tokena autoryzacji określa, który token usługi jest wymagany przez usługę TripService
. Zapewnia też wymagane tripId
na potrzeby kontekstu.
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 korzystać z pakietu SDK Consumer SDK, aplikacja musi zainicjować ConsumerApi
asynchronicznie. Interfejs API to jedyny system.
Metoda inicjowania zajmuje AuthTokenFactory
. Fabryka generuje w razie potrzeby 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 klienta za pomocą pakietu SDK.
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 i mechanizmy renderowania map
Pakiet Consumer SDK w wersji 2.x.x obsługuje pakiet Maps SDK na Androida w wersji 18.1.0 lub nowszej. W tabeli poniżej znajdziesz podsumowanie domyślnego mechanizmu renderowania według wersji pakietu SDK Map Google oraz informacje o obsłudze obu mechanizmów renderowania. Zalecamy korzystanie z najnowszego mechanizmu renderowania, jeśli jednak chcesz użyć starszej wersji mechanizmu renderowania, możesz ją jednoznacznie określić za pomocą metody MapsInitializer.initialize()
.
Wersja pakietu SDK Maps | Obsługuje najnowszy mechanizm renderowania | Obsługuje starszy mechanizm renderowania | Domyślny mechanizm renderowania |
---|---|---|---|
Wersja 18.1.0 i starsze | Tak | Tak | Starsza wersja* |
V18.2.0 | Tak | Tak | Najnowsze |
* Po wdrożeniu nowego mechanizmu renderowania Map domyślnym ustawieniem będzie „Najnowsza wersja mechanizmu renderowania”.
Dodaj pakiet Maps SDK jako zależność
Gradle
Dodaj do build.gradle
:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:VERSION_NUMBER"
}
Maven
Dodaj do 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 Maps SDK przed zainicjowaniem pakietu dla klientów indywidualnych
W klasie Application
lub startowej klasie Activity
wywołaj MapsInitializer.initialize() i poczekaj na wynik żądania mechanizmu renderowania, zanim zainicjujesz pakiet SDK dla klientów indywidualnych.
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 swojej aplikacji możesz utworzyć za pomocą ConsumerMapFragment
lub ConsumerMapView
. ConsumerMapFragment
pozwala zdefiniować mapę za pomocą Fragment
, a ConsumerMapView
pozwala używać View
. Funkcje udostępniania przejazdów są takie same zarówno w usłudze ConsumerMapView
, jak i w ConsumerMapFragment
. Możesz wybrać taką opcję w zależności od tego, czy wersja View
czy Fragment
lepiej sprawdzi się w Twojej aplikacji.
Dodanie obsługi elementów rysowanych w interfejsie API 19 (KitKat) i wektorowych
Jeśli projekt Twojej aplikacji wymaga obsługi urządzeń z interfejsem API 19 (KitKat) i wektorowych obiektów rysowalnych, dodaj ten kod do swojej aktywności. Rozszerzenie AppCompatActivity
umożliwia korzystanie z obiektów rysowania wektorów w pakiecie SDK dla klientów indywidualnych.
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
Tworzysz mapę do wyświetlania udostępniania podróży we fragmencie Androida lub widoku zdefiniowanym w pliku XML układu aplikacji (w lokalizacji /res/layout
). Fragment (lub widok) daje potem dostęp do mapy udostępniania trasy, do której aplikacja może uzyskiwać dostęp i ją modyfikować. Mapa zawiera też uchwyt do ConsumerController
, który umożliwia aplikacji dostosowywanie i dostosowywanie sposobu udostępniania podróży.
Udostępnianie mapy i kontrolera
Mapę udostępniania trasy możesz zdefiniować jako fragment (za pomocą ConsumerMapFragment
) lub widok (za pomocą ConsumerMapView
), jak pokazano w tym przykładzie kodu. Metoda onCreate()
powinna następnie wywołać metodę getConsumerGoogleMapAsync(callback)
, która zwraca w wywołaniu zwrotnym asynchronicznie wartość ConsumerGoogleMap
. Następnie za pomocą ConsumerGoogleMap
możesz wyświetlić informacje o trasie, które można zaktualizować w razie potrzeby aplikacji.
ConsumerMapFragment
Definiujesz ten fragment w pliku XML układu aplikacji, zgodnie z poniższym przykładem 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()!!
}
}
)
}
}
ConsumerMapView
Widok można wykorzystać we fragmencie lub w 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" />
Wywołanie getConsumerGoogleMapAsync()
powinno pochodzić z onCreate()
. Oprócz parametru wywołania zwrotnego wymagany jest element zawierający aktywność lub fragment i zasadę GoogleMapOptions
(która może być pusta), która zawiera atrybuty konfiguracji MapView
. Klasa bazowa działania lub fragmentu musi być albo FragmentActivity
albo obsługą Fragment
, ponieważ zapewnia dostęp do 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 dla elementu MapView
w aktywności. Jedyna różnica jest taka, że fragment rozszerza układ zawierający element MapView
w metodzie fragmentu 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)
}
}
Dostosowywanie powiększenia aparatu w celu skoncentrowania się na podróży
Domyślny przycisk Moja lokalizacja wbudowany w pakiet SDK Map Google kieruje aparat na lokalizację urządzenia.
Jeśli aktywna jest sesja udostępniania trasy, możesz ustawić aparat tak, aby koncentrować się na trasie, a nie na lokalizacji urządzenia.
Wbudowany pakiet SDK dla użytkowników urządzeń z Androidem: AutoCamera
Aby umożliwić Ci skupienie się na podróży, a nie na lokalizacji urządzenia, pakiet Consumer SDK udostępnia domyślnie włączoną funkcję AutoCamera Kamera robi zbliżenie, by skupić się na trasie współdzielonej podróży 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ć automatyczną kamerę za pomocą funkcji ConsumerController.setAutoCameraEnabled().
ConsumerController.getCameraUpdate() zwraca w danym momencie zalecane wartości progowe kamery. Następnie możesz podać ten element 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 mapą w aplikacji, musisz mieć dostęp do ConsumerGoogleMap
i ConsumerController
.
ConsumerMapFragment
i ConsumerMapView
asynchronicznie zwracają ConsumerGoogleMap
w ConsumerMapReadyCallback
.
ConsumerGoogleMap
zwraca
ConsumerController
od: getConsumerController()
. Aby uzyskać dostęp do usług ConsumerGoogleMap
i ConsumerController
, wykonaj te czynności.
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
to klasa kodu dla klasy GoogleMap
. Zapewnia aplikacji możliwość interakcji z mapą za pomocą interfejsu API odpowiednika GoogleMap
. Dzięki mapie dla klientów aplikacja i wspólne przejazdy mogą płynnie współdziałać z tą samą bazą danych GoogleMap. Na przykład GoogleMap
umożliwia rejestrację tylko z jednym wywołaniem zwrotnym, ale ConsumerGoogleMap
obsługuje podwójne zarejestrowane wywołania zwrotne.
Te wywołania zwrotne umożliwiają aplikacji i udostępnianiu przejazdów rejestrowanie wywołań zwrotnych, które są wywoływane sekwencyjnie.
ConsumerController
ConsumerController
umożliwia dostęp do funkcji wspólnych przejazdów, np. monitorowania przejazdów, kontrolowania ich stanu i ustawiania lokalizacji.
Konfigurowanie udostępniania podróży
Gdy backend dopasuje klienta do pojazdu, użyj funkcji JourneySharingSession
, aby rozpocząć interfejs udostępniania ścieżki. Udostępnianie trasy 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 przyjęto, że usługi backendu są dostępne i że usługi dopasowywania konsumentów do pojazdów działają.
Zarejestruj nasłuch w obiekcie
TripModel
, aby uzyskać szczegółowe informacje o podróży, takie jak szacowany czas przyjazdu (szacowany czas przyjazdu) i przebyta odległość, jaką musi przebyć 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óż w aplikacji
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ę
Pamiętaj, aby zatrzymać udostępnianie ścieżek, gdy nie jest już potrzebne, na przykład w przypadku zniszczenia aktywności hosta. Zatrzymanie udostępniania ścieżek powoduje też zatrzymanie żądań sieciowych wysyłanych do Fleet Engine i zapobiega wyciekom pamięci.
Ten przykładowy kod pokazuje, jak zatrzymać udostępnianie przebiegu.
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 związanych z podróżą
Metoda onTripRefreshError
wyświetla błędy, które występują podczas monitorowania podróży.
Mapowanie błędów pakietu Consumer SDK jest zgodne z tymi samymi wytycznymi dotyczącymi protokołu HTTP/RPC, które są stosowane w przypadku Google Cloud Platform.
Typowe błędy wykrywane podczas monitorowania podróży to między innymi:
HTTP | RPC | Opis |
---|---|---|
400 | INVALID_ARGUMENT | Klient podał nieprawidłową nazwę podróży. Nazwa podróży musi mieć format providers/{provider_id}/trips/{trip_id} .
provider_id musi być identyfikatorem projektu Cloud należącego do dostawcy usług. |
401 | BEZ UWIERZYTELNIANIA | Żądanie nie zostało uwierzytelnione z powodu nieprawidłowego tokena JWT. Ten błąd występuje, jeśli token JWT zostanie podpisany bez identyfikatora podróży lub token JWT wygasł. |
403 | PERMISSION_DENIED | 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 token jest podpisany identyfikatorem podróży, który nie pasuje do żądanego identyfikatora podróży. |
429 | RESOURCE_EXHAUSTED | Limit zasobów wynosi zero lub szybkość ruchu przekracza limit. |
503 | PRODUKT NIEDOSTĘPNY | Usługa niedostępna Zwykle serwer jest niedostępny. |
504 | DEADLINE_EXCEEDED | Przekroczono termin prośby. Dzieje się tak tylko wtedy, gdy osoba wywołująca ustawi termin krótszy niż domyślny termin w metodzie (tzn. żądany termin jest niewystarczający na przetworzenie żądania przez serwer), a żądanie nie zostało ukończone w wyznaczonym terminie. |
Więcej informacji znajdziesz w artykule Obsługa błędów w pakietach SDK dla klientów indywidualnych.