Вы можете использовать Consumer SDK для создания и запуска базового потребительского приложения, интегрированного с серверными службами решения On-demand Rides and Delivery Solution. Вы можете создать приложение «Прогресс поездки и заказа», которое может отображать активную поездку, реагировать на обновления поездки и обрабатывать ошибки поездки.
Поскольку Consumer SDK имеет модульную архитектуру, вы можете использовать части API, которые хотите использовать для своего конкретного приложения, и интегрировать их со своими собственными API, серверными службами, предоставляемыми Fleet Engine, а также дополнительными API платформы Google Maps. .
Минимальные системные требования
Мобильное устройство должно работать под управлением Android 6.0 (уровень API 23) или более поздней версии.
Конфигурация сборки и зависимостей
Потребительский SDK версии 1.99.0 и более поздних доступен в репозитории Google Maven. Ранее использовавшийся канал частного репозитория устарел.
Градл
Добавьте в файл build.gradle
следующее:
repositories {
...
google()
}
Мавен
Добавьте в файл pom.xml
следующее:
<project>
...
<repositories>
<repository>
<id>google-maven-repository</id>
<url>https://maven.google.com</url>
</repository>
</repositories>
...
</project>
Конфигурация проекта
Чтобы использовать Consumer SDK для Android, ваше приложение должно быть нацелено на minSdkVersion
23 или выше.
Чтобы запустить приложение, созданное с помощью Consumer SDK, на устройстве Android должны быть установлены службы Google Play .
Настройте свой проект разработки
Чтобы настроить проект разработки и получить ключ API для проекта в Google Cloud Console:
Создайте новый проект Google Cloud Console или выберите существующий проект для использования с Consumer SDK. Подождите несколько минут, пока новый проект не появится в Google Cloud Console.
Чтобы запустить демонстрационное приложение, у вашего проекта должен быть доступ к Maps SDK для Android. В Google Cloud Console выберите API и службы > Библиотека , затем найдите и включите Maps SDK для Android.
Получите ключ API для проекта, выбрав API и службы > Учетные данные > Создать учетные данные > Ключ API . Дополнительную информацию о получении ключа API см. в разделе Получение ключа API .
Добавьте Consumer SDK в свое приложение
Consumer SDK доступен через частный репозиторий Maven. Репозиторий включает файлы объектной модели проекта SDK (.pom) и документацию Javadocs. Чтобы добавить Consumer SDK в ваше приложение:
Настройте свою среду для доступа к хост-репозиторию Maven, как описано в предыдущем разделе.
Если у вас есть конфигурация централизованного управления зависимостями, объявленная в
settings.gradle
, отключите ее следующим образом.Удалите следующий блок кода в
settings.gradle
:import org.gradle.api.initialization.resolve.RepositoriesMode dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Добавьте следующую зависимость в вашу конфигурацию Gradle или Maven, заменив заполнитель
VERSION_NUMBER
на нужную версию Consumer SDK.Градл
Добавьте в свой
build.gradle
следующее:dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Мавен
Добавьте следующее в ваш
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
Consumer SDK зависит от Maps SDK. Эта зависимость настроена таким образом, что если версия Maps SDK не определена явно в файле конфигурации сборки, как показано ниже, при выпуске новой версии Maps SDK Consumer SDK продолжит использовать минимальную поддерживаемую версию Maps SDK. требуемое им.
Градл
Добавьте в свой
build.gradle
следующее:dependencies { ... implementation 'com.google.android.gms:play-services-maps:18.1.0' }
Мавен
Добавьте следующее в ваш
pom.xml
:<dependencies> ... <dependency> <groupId>com.google.android.gms</groupId> <artifactId>play-services-maps</artifactId> <version>18.1.0</version> </dependency> </dependencies>
Добавьте ключ API в свое приложение
Добавив Consumer SDK в свое приложение, добавьте в свое приложение ключ API. Вы должны использовать ключ API проекта, полученный при настройке проекта разработки .
В этом разделе описывается, как хранить ключ API, чтобы ваше приложение могло более безопасно ссылаться на него. Вам не следует проверять свой ключ API в системе контроля версий. Он должен храниться в файле local.properties
, который находится в корневом каталоге вашего проекта. Дополнительные сведения о файле local.properties
см. в разделе Файлы свойств Gradle .
Чтобы упростить эту задачу, вы можете использовать плагин Secrets Gradle для Android .
Чтобы установить плагин и сохранить ключ API:
Откройте файл
build.gradle
корневого уровня и добавьте следующий код в элементdependencies
вbuildscript
.классный
buildscript { dependencies { // ... classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0" } }
Котлин
buildscript { dependencies { // ... classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0") } }
Откройте файл
build.gradle
уровня приложения и добавьте следующий код в элементplugins
.классный
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Котлин
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
Если вы используете Android Studio, синхронизируйте свой проект с Gradle .
Откройте
local.properties
в каталоге уровня вашего проекта, а затем добавьте следующий код. ЗаменитеYOUR_API_KEY
своим ключом API.MAPS_API_KEY=YOUR_API_KEY
В файле
AndroidManifest.xml
перейдите по адресуcom.google.android.geo.API_KEY
и обновите атрибутandroid:value
следующим образом:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
В следующем примере показан полный манифест примера приложения:
<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>
Включите необходимую атрибуцию в свое приложение
Если вы используете Consumer SDK в своем приложении, вы должны включить текст указания авторства и лицензии с открытым исходным кодом в раздел юридических уведомлений вашего приложения. Лучше всего включить атрибуцию как независимый пункт меню или как часть пункта меню «О программе» .
Информацию о лицензиях можно найти в файле Third_party_licenses.txt в разархивированном файле AAR.
Инструкции по включению уведомлений об открытом исходном коде см. на странице https://developers.google.com/android/guides/opensource .
Аутентификация потребительского SDK
Consumer SDK обеспечивает аутентификацию с использованием веб-токенов JSON. Веб-токен JSON (JWT) — это токен доступа на основе JSON, который предоставляет одно или несколько утверждений к службе. Например, сервер может сгенерировать токен с утверждением «вошел в систему как администратор» и предоставить его клиенту. Затем клиент может использовать этот токен, чтобы доказать, что он вошел в систему как администратор.
Consumer SDK использует веб-токен JSON, предоставленный приложением, для связи с Fleet Engine. Дополнительную информацию см. в разделе «Аутентификация и авторизация Fleet Engine» .
Токен авторизации должен включать утверждение tripid:TRIP_ID
в заголовок authorization
токена, где TRIP_ID
— это идентификатор поездки. Это дает Consumer SDK доступ к деталям поездки, включая положение транспортного средства, маршрут и расчетное время прибытия.
Обратные вызовы JSON Web Token
Consumer SDK регистрирует обратный вызов токена авторизации в приложении во время инициализации. SDK вызывает приложение, чтобы получить токен для всех сетевых запросов, требующих авторизации.
Мы настоятельно рекомендуем кэшировать токены авторизации реализации обратного вызова и обновлять их только по истечении срока expiry
. Токены должны выпускаться со сроком действия один час.
Обратный вызов токена авторизации указывает, какой токен службы необходим для службы TripService
. Он также предоставляет необходимый tripId
для контекста.
В следующем примере кода показано, как реализовать обратный вызов токена авторизации.
Ява
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;
}
}
Котлин
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
Прежде чем выполнять эти процедуры, предполагается, что вы включили соответствующие службы и Consumer SDK.
Получить экземпляр ConsumerApi
Чтобы использовать Consumer SDK, вашему приложению необходимо асинхронно инициализировать ConsumerApi
. API является одноэлементным. Метод инициализации принимает AuthTokenFactory
. При необходимости фабрика генерирует для пользователя новые токены JWT.
providerId
— это идентификатор вашего проекта Google Cloud. Дополнительную информацию о создании проекта см. в руководстве пользователя Fleet Engine .
Ваше приложение должно реализовать AuthTokenFactory
, как описано в разделе «Аутентификация Consumer SDK» .
Ява
Task<ConsumerApi> consumerApiTask = ConsumerApi.initialize(
this, "myProviderId", authTokenFactory);
consumerApiTask.addOnSuccessListener(
consumerApi -> this.consumerApi = consumerApi);
Котлин
val consumerApiTask =
ConsumerApi.initialize(this, "myProviderId", authTokenFactory)
consumerApiTask?.addOnSuccessListener { consumerApi: ConsumerApi ->
this@YourActivity.consumerApi = consumerApi
}
Maps SDK и средства рендеринга карт
Consumer SDK v2.xx поддерживает Maps SDK для Android v18.1.0 и более поздних версий. В таблице ниже приведены средства визуализации по умолчанию в зависимости от версии Maps SDK и возможности поддержки обоих средств визуализации. Мы рекомендуем использовать последнюю версию средства визуализации, однако, если вам нужно использовать устаревшую систему визуализации, вы можете явно указать ее с помощью MapsInitializer.initialize()
.
Версия SDK Карт | Поддерживает последний рендерер | Поддерживает устаревший рендерер | Средство визуализации по умолчанию |
---|---|---|---|
Версия 18.1.0 и ниже | Да | Да | Наследие* |
В18.2.0 | Да | Да | Последний |
* С выпуском нового средства визуализации карт по умолчанию будет использоваться последняя версия средства визуализации.
Добавьте Maps SDK в качестве зависимости
Градл
Добавьте следующее в свой build.gradle
:
dependencies {
//...
implementation "com.google.android.gms:play-services-maps:VERSION_NUMBER"
}
Мавен
Добавьте следующее в ваш pom.xml
:
<dependencies>
...
<dependency>
<groupId>com.google.android.gms</groupId>
<artifactId>play-services-maps</artifactId>
<version>18.1.0</version>
</dependency>
</dependencies>
Инициализируйте Maps SDK перед инициализацией Consumer SDK.
В классе Application
или запуска Activity
вызовите MapsInitializer.initialize() и дождитесь результата запроса средства визуализации, прежде чем инициализировать Consumer SDK.
Ява
@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();
}
});
}
Котлин
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()
}
})
}
Создайте пользовательский интерфейс
Вы можете использовать ConsumerMapFragment
или ConsumerMapView
для создания пользовательского интерфейса для вашего приложения. ConsumerMapFragment
позволяет вам определить карту с помощью Fragment
, а ConsumerMapView
позволяет использовать View
. Функциональность совместного использования поездок одинакова как в ConsumerMapView
, так и в ConsumerMapFragment
, поэтому вы можете выбрать один из них в зависимости от того, какой вариант View
или Fragment
лучше подходит для вашего приложения.
Добавлена поддержка API 19 (KitKat) и векторных изображений.
Если дизайн вашего приложения требует поддержки устройств API 19 (KitKat) и векторных изображений, добавьте следующий код в свою активность. Этот код расширяет AppCompatActivity
для использования векторных рисунков в Consumer SDK.
Ява
// ...
import android.support.v7.app.AppCompatActivity;
// ...
public class ConsumerTestActivity extends AppCompatActivity {
// ...
}
Котлин
// ...
import android.support.v7.app.AppCompatActivity
// ...
class ConsumerTestActivity : AppCompatActivity() {
// ...
}
Добавьте фрагмент карты или вид
Вы создаете карту для отображения совместного путешествия либо во фрагменте Android, либо в представлении, которое вы определяете в XML-файле макета приложения (расположенном в /res/layout
). Затем фрагмент (или представление) предоставляет доступ к карте совместного путешествия, к которой ваше приложение может обращаться и изменять. Карта также предоставляет дескриптор ConsumerController
, который позволяет вашему приложению контролировать и настраивать процесс обмена информацией о путешествии.
Карта совместного использования путешествий и контроллер
Вы определяете карту совместного использования пути либо как фрагмент (с помощью ConsumerMapFragment
), либо как представление (с помощью ConsumerMapView
), как показано в следующем примере кода. Затем ваш метод onCreate()
должен вызвать getConsumerGoogleMapAsync(callback)
, который асинхронно возвращает ConsumerGoogleMap
в обратном вызове. Затем вы используете ConsumerGoogleMap
для отображения информации о поездках, и ее можно обновлять по мере необходимости вашего приложения.
ПотребительКартаФрагмент
Вы определяете этот фрагмент в XML-файле макета приложения, как показано в следующем примере кода.
<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" />
Вызов getConsumerGoogleMapAsync()
должен исходить из метода onCreate()
.
Ява
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();
}
});
}
}
}
Котлин
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
Представление можно использовать либо во фрагменте, либо в действии, как определено в вашем 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" />
Вызов getConsumerGoogleMapAsync()
должен быть из onCreate()
. В дополнение к параметру обратного вызова для него требуется содержащее действие или фрагмент, а также GoogleMapOptions
(который может иметь значение null), содержащий атрибуты конфигурации для MapView
. Базовый класс действия или фрагмента должен быть либо FragmentActivity
, либо вспомогательным Fragment
(соответственно), поскольку они обеспечивают доступ к его жизненному циклу.
Ява
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);
}
}
}
Котлин
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,
)
}
}
MapView
во фрагменте аналогичен приведенному выше примеру для MapView
в действии, за исключением того, что фрагмент раздувает макет, который включает MapView
в методе onCreateView()
фрагмента.
Ява
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);
}
}
Котлин
class MapViewInFragment : Fragment() {
override fun onCreateView(
layoutInflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
return layoutInflater.inflate(R.layout.consumer_map_view, viewGroup, false)
}
}
Настройка масштаба камеры, чтобы сосредоточиться на путешествии
Кнопка «Мое местоположение» по умолчанию, встроенная в Maps SDK, центрирует камеру по местоположению устройства.
Если существует активный сеанс обмена информацией о путешествии, вы можете отцентрировать камеру, чтобы сфокусироваться на путешествии, а не на местоположении устройства.
Потребительский SDK для встроенного решения Android: AutoCamera
Чтобы вы могли сосредоточиться на путешествии, а не на местоположении устройства, Consumer SDK предоставляет функцию AutoCamera, которая включена по умолчанию. Камера масштабируется, чтобы сфокусироваться на маршруте совместного путешествия и следующей путевой точке.
Настройка поведения камеры
Если вам требуется больший контроль над поведением камеры, вы можете отключить или включить автокамеру с помощью ConsumerController.setAutoCameraEnabled() .
ConsumerController.getCameraUpdate() возвращает рекомендуемые границы камеры на данный момент. Затем вы можете предоставить этот CameraUpdate
в качестве аргумента GoogleMap.moveCamera() или GoogleMap.animateCamera() .
Доступ к совместному использованию поездок и картам
Для поддержки совместного использования поездок и взаимодействия с картами в вашем приложении вам необходим доступ к ConsumerGoogleMap
и ConsumerController
. ConsumerMapFragment
и ConsumerMapView
асинхронно возвращают ConsumerGoogleMap
в ConsumerMapReadyCallback
. ConsumerGoogleMap
возвращает ConsumerController
из getConsumerController()
. Вы можете получить доступ к ConsumerGoogleMap
и ConsumerController
следующим образом.
Ява
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);
Котлин
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,
}
)
ПотребительGoogleКарта
ConsumerGoogleMap
— это класс-оболочка для класса GoogleMap
. Он предоставляет вашему приложению возможность взаимодействовать с картой с помощью API, эквивалентного GoogleMap
. Использование карты потребителя позволяет вашему приложению и сервису совместного использования поездок беспрепятственно взаимодействовать с одной и той же базовой картой GoogleMap. Например, GoogleMap
допускает только одну регистрацию обратного вызова, а ConsumerGoogleMap
поддерживает двойные зарегистрированные обратные вызовы. Эти обратные вызовы позволяют вашему приложению и совместному использованию поездок регистрировать обратные вызовы, которые вызываются последовательно.
ПотребительКонтроллер
ConsumerController
предоставляет доступ к функциям совместного использования поездок, таким как мониторинг поездок, контроль статуса поездки и настройка местоположения.
Настройте совместное путешествие
После того как серверная часть сопоставила потребителя с транспортным средством, используйте JourneySharingSession
, чтобы запустить пользовательский интерфейс совместного использования поездок. Функция обмена информацией о поездках показывает местоположение и маршрут соответствующего автомобиля. После внедрения SDK в ваше приложение вы можете добавить функции мониторинга поездок, прослушивания обновлений и обработки ошибок. Следующие процедуры предполагают, что серверные службы установлены и ваши службы по сопоставлению потребителей с транспортными средствами работают.
Зарегистрируйте прослушиватель в объекте
TripModel
, чтобы получать подробные сведения о поездке, например расчетное время прибытия (ETA) и расстояние, которое необходимо преодолеть транспортному средству до прибытия.Ява
// 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) { // ... } // ... });
Котлин
// 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?, ) { // ... } // ... })
Настройте свою поездку с помощью
TripModelOptions
.Ява
// Set refresh interval to 2 seconds. TripModelOptions tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build(); tripModel.setTripModelOptions(tripOptions);
Котлин
// Set refresh interval to 2 seconds. val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build() tripModel.setTripModelOptions(tripOptions)
Прекратить делиться поездками
Обязательно прекращайте делиться поездками, когда в них больше нет необходимости, например, когда активность хоста уничтожена. Прекращение совместного использования маршрутов также останавливает сетевые запросы к Fleet Engine и предотвращает утечки памяти.
В следующем примере кода показано, как прекратить совместное использование поездок.
Ява
public class MainActivity extends AppCompatActivity
implements ConsumerViewModel.JourneySharingListener {
// Class implementation
@Override
protected void onDestroy() {
super.onDestroy();
if (journeySharingSession != null) {
journeySharingSession.stop();
}
}
}
Котлин
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
// Class implementation
override fun onDestroy() {
super.onDestroy()
journeySharingSession?.stop()
}
}
Обработка ошибок в поездках
Метод onTripRefreshError
выявляет ошибки, возникающие во время мониторинга поездки. Сопоставление ошибок Consumer SDK соответствует тем же правилам HTTP/RPC, что и для Google Cloud Platform . К частым ошибкам, возникающим во время мониторинга поездки, относятся следующие:
HTTP | ПКП | Описание |
---|---|---|
400 | INVALID_ARGUMENT | Клиент указал неверное название поездки. Название поездки должно иметь формат providers/{provider_id}/trips/{trip_id} . Provider_id должен быть идентификатором облачного проекта, принадлежащего поставщику услуг. |
401 | НЕ АУТЕНТИФИЦИРОВАННЫЙ | Запрос не аутентифицирован из-за недействительного токена JWT. Эта ошибка произойдет, если токен JWT подписан без идентификатора поездки или срок действия токена JWT истек. |
403 | ДОСТУП ЗАПРЕЩЕН | Клиент не имеет достаточного разрешения. Эта ошибка возникает, если токен JWT недействителен, у клиента нет разрешения или API не включен для клиентского проекта. Токен JWT может отсутствовать или токен подписан идентификатором поездки, который не соответствует запрошенному идентификатору поездки. |
429 | RESOURCE_EXHAUSTED | Квота ресурса равна нулю или скорость трафика превышает лимит. |
503 | НЕДОСТУПНО | Сервис недоступен. Обычно сервер не работает. |
504 | DEADLINE_EXCEEDED | Срок запроса истек. Это произойдет только в том случае, если вызывающая сторона установит крайний срок, который короче, чем крайний срок метода по умолчанию (т. е. запрошенного срока недостаточно для того, чтобы сервер обработал запрос), и запрос не был завершен в течение этого срока. |
Дополнительные сведения см. в разделе Обработка ошибок Consumer SDK .