Consumer SDK を使用すると、オンデマンド配車および配達ソリューションのバックエンド サービスと統合した基本的なコンシューマー アプリをビルドして実行できます。アクティブなルートを表示し、ルートの更新情報に対応し、ルートエラーを処理できる Trip and Order Progress アプリを作成できます。
コンシューマ SDK にはモジュール アーキテクチャがあるため、特定のアプリで使用する API の部分を使用して、独自の API、Fleet Engine が提供するバックエンド サービス、Google Maps Platform の追加 API と統合できます。
最小システム要件
モバイル デバイスが Android 5.0(API レベル 21)以降を実行している必要があります。
Prerequisites
輸送と物流の Android SDK は、Artifact Registry Maven リポジトリに公開されます。リポジトリには、SDK のプロジェクト オブジェクト モデル(.pom)ファイルとオフライン Javadocs が含まれています。
アクセス権の取得
Google Workspace を使用している場合は、オンボーディング時に google-maps-platform-sdk-users@workspacedomain.com
などのワークスペース グループを作成し、Google に名前を指定します。これはおすすめの方法です。
次に、ワークスペース グループが、Maven リポジトリ gmp-artifacts/transportation
へのアクセスを許可する許可リストに追加されます。アクセス権を必要とするユーザーのメールアドレスとサービス アカウントのメールアドレスがこのリストに含まれていることを確認します。
組織で Workspace グループを作成できない場合は、これらのアーティファクトにアクセスする必要があるユーザーとサービス アカウントのメールアドレスのリストを Google に送信します。
ローカルでの開発
ローカル開発では、Cloud SDK でログインするだけで十分です。
gcloud
gcloud auth login
ログインに使用するメールアドレスは、Workspace グループのメンバーである必要があります。
自動化(ビルドシステムまたは継続的インテグレーション)
ベスト プラクティスに従って自動化ホストを設定します。
プロセスが Google Cloud 環境内で実行されている場合は、自動認証情報検出を使用します。
それ以外の場合は、ホストのファイル システムの安全な場所にサービス アカウント キー ファイルを保存し、GOOGLE_APPLICATION_CREDENTIALS 環境変数を適切に設定します。
認証情報に関連付けられたサービス アカウントのメールアドレスは、Workspace グループのメンバーである必要があります。
構成
ユーザーまたはサービスの認証情報を自動的に検出するように Maven または Gradle を構成します。
Gradle
プロジェクト ルート モジュール build.gradle
ファイルではなく、アプリ モジュールの build.gradle
ファイルに追加します。
plugins {
id "com.google.cloud.artifactregistry.gradle-plugin" version "2.1.5"
}
repositories {
maven {
url "artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation"
}
}
Maven
pom.xml
に次の行を追加します。
<repositories>
<repository>
<id>gmp-artifacts</id>
<url>artifactregistry://us-west2-maven.pkg.dev/gmp-artifacts/transportation</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.1.5</version>
</extension>
</extensions>
</build>
アクセスの確認については、Java パッケージの管理をご覧ください。
Project Configuration
Consumer SDK for Android を使用するには、アプリで minSdkVersion
19 以降をターゲットにする必要があります。
Consumer SDK を使用してビルドされたアプリを実行するには、Android デバイスに Google Play 開発者サービスがインストールされている必要があります。
開発プロジェクトを設定する
開発プロジェクトを設定して、Google Cloud Console でプロジェクトの API キーを取得するには:
Consumer SDK で使用する Google Cloud Console プロジェクトを新規作成するか、既存のプロジェクトを選択します。新しいプロジェクトが Google Cloud Console に表示されるまで数分待ちます。
デモアプリを実行するには、プロジェクトに Maps SDK for Android へのアクセス権が付与されている必要があります。Google Cloud Console で、[API とサービス] > [ライブラリ] を選択し、Maps SDK for Android を検索して有効にします。
プロジェクトの API キーを取得するには、[API とサービス] > [認証情報] > [認証情報を作成] > [API キー] を選択します。API キーの取得について詳しくは、API キーを取得するをご覧ください。
コンシューマ SDK をアプリに追加する
Consumer SDK は、専用の Maven リポジトリを介して入手できます。リポジトリには、SDK の Project Object Model(.pom)ファイルと Javadocs が含まれています。コンシューマ 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
プレースホルダは、目的のバージョンの SDK に置き換えてください。Gradle
build.gradle
に次の行を追加します。dependencies { ... implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-consumer:VERSION_NUMBER' }
Maven
pom.xml
に次の行を追加します。<dependencies> ... <dependency> <groupId>com.google.android.libraries.mapsplatform.transportation</groupId> <artifactId>transportation-consumer</artifactId> <version>VERSION_NUMBER</version> </dependency> </dependencies>
アプリに API キーを追加する
コンシューマ SDK をアプリに追加したら、API キーをアプリに追加します。開発プロジェクトを設定したときに取得したプロジェクト API キーを使用する必要があります。
このセクションでは、アプリでより安全に参照できるように API キーを保存する方法について説明します。API キーをバージョン管理システムにチェックインしないでください。これは、プロジェクトのルート ディレクトリにある local.properties
ファイルに保存する必要があります。local.properties
ファイルの詳細については、Gradle プロパティ ファイルをご覧ください。
このタスクを効率化するには、Android 用 Secrets Gradle プラグインを使用します。
プラグインをインストールして API キーを保存するには:
ルートレベルの
build.gradle
ファイルを開き、buildscript
の下にあるdependencies
要素に次のコードを追加します。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") } }
アプリレベルの
build.gradle
ファイルを開き、次のコードをplugins
要素に追加します。Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
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>
必須の帰属情報をアプリに含める
アプリでコンシューマ SDK を使用する場合は、アプリの法的通知セクションの一部として、アトリビューション テキストとオープンソース ライセンスを含める必要があります。アトリビューションは、独立したメニュー項目として、または [概要] メニュー項目の一部として含めることをおすすめします。
必要なアトリビューション テキストとオープンソース ライセンスは、ライドシェアリング コンシューマ SDK の zip ファイルで確認できます。
NOTICE.txt
LICENSES.txt
コンシューマ SDK の認証
Consumer SDK では、JSON Web Token を使用して認証を行います。JSON Web Token(JWT)は、サービスに対して 1 つ以上のクレームを提供する JSON ベースのアクセス トークンです。たとえば、サーバーは「管理者としてログインしている」というクレームを持つトークンを生成し、それをクライアントに提供できます。クライアントはそのトークンを使用して、管理者としてログインしていることを証明できます。
コンシューマ SDK は、アプリケーションが提供する JSON ウェブトークンを使用して Fleet Engine と通信します。詳細については、Fleet Engine の認証と認可をご覧ください。
認証トークンを使用すると、次の Fleet Engine サービスにアクセスできます。
TripService
- 車両の位置情報、ルート、到着予定時刻など、旅程の詳細にコンシューマ SDK がアクセスできるようにします。トリップ サービスの認証トークンは、トークンのauthorization
ヘッダーにtripid:TRIP_ID
クレームを含める必要があります。TRIP_ID
はルート ID です。VehicleService
- 車両密度レイヤを表示し、到着地点の到着予定時刻を推定するために、車両の移動した車両の場所に関する情報をコンシューマ SDK に提供します。コンシューマ SDK はファジングされた位置情報のみを使用するため、車両サービスの認証トークンにvehicleid
クレームは必要ありません。
JSON Web Token コールバック
コンシューマ SDK は、初期化時に認証トークンをコールバックに登録します。SDK はアプリケーションを呼び出して、承認が必要なすべてのネットワーク リクエストのトークンを取得します。
コールバックの実装では、認証トークンをキャッシュし、expiry
時間が経過した場合にのみ更新することを強くおすすめします。トークンは、1 時間の有効期限で発行する必要があります。
認証トークン コールバックは、TripService
サービスに必要なサービス トークンを指定します。また、コンテキストに必要な tripId
も提供されます。
次のコード例は、認証トークンのコールバックを実装する方法を示しています。
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 を初期化する
この手順は、適切なサービスとコンシューマ SDK が有効になっていることを前提としています。
ConsumerApi
インスタンスを取得する
コンシューマ SDK を使用するには、アプリで非同期的に ConsumerApi
を初期化する必要があります。API はシングルトンです。
初期化メソッドは AuthTokenFactory
を受け取ります。ファクトリは必要に応じて、ユーザー用に新しい JWT トークンを生成します。
providerId
は、Google Cloud プロジェクトのプロジェクト ID です。プロジェクトの作成方法については、Fleet Engine ユーザーガイドをご覧ください。
アプリに AuthTokenFactory
を実装する必要があります。詳細については、コンシューマ 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
}
ユーザー インターフェースを作成する
アプリケーションのユーザー インターフェースは、ConsumerMapFragment
または ConsumerMapView
を使用して作成できます。ConsumerMapFragment
では Fragment
を使用して地図を定義でき、ConsumerMapView
では View
を使用できます。ライドシェア機能は ConsumerMapView
と ConsumerMapFragment
で同じであるため、View
と Fragment
のどちらがアプリに適しているかに基づいて、いずれかを選択できます。
API 19(KitKat)とベクター型ドローアブルのサポートを追加
アプリ設計で API 19(KitKat)デバイスとベクター型ドローアブルのサポートが必要な場合は、アクティビティに次のコードを追加します。このコードは、コンシューマ SDK で AppCompatActivity
を拡張して、ベクター型ドローアブルを使用します。
Java
// ...
import android.support.v7.app.AppCompatActivity;
// ...
public class ConsumerTestActivity extends AppCompatActivity {
// ...
}
Kotlin
// ...
import android.support.v7.app.AppCompatActivity
// ...
class ConsumerTestActivity : AppCompatActivity() {
// ...
}
地図のフラグメントまたはビューを追加する
アプリ レイアウトの XML ファイル(/res/layout
にあります)で定義した Android フラグメントまたはビューにジャーニー共有を表示する地図を作成します。次に、フラグメント(またはビュー)は、アプリがアクセスして変更できるジャーニー共有マップへのアクセスを提供します。この地図により、ConsumerController
でハンドルも提供され、アプリでジャーニー共有のエクスペリエンスを制御、カスタマイズできます。
移動経路マップとコントローラ
次のコード共有次に示すように、ジャーニー共有マップをフラグメント(ConsumerMapFragment
を使用)またはビュー(ConsumerMapView
を使用)として定義します。次に、onCreate()
メソッドは getConsumerGoogleMapAsync(callback)
を呼び出します。これにより、コールバックで非同期に ConsumerGoogleMap
が返されます。その後、ConsumerGoogleMap
を使用してジャーニーを共有し、アプリの要件に応じて更新できます。
ConsumerMapFragment
次のコード例に示すように、アプリ レイアウト 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()
メソッドから行う必要があります。
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
このビューは、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()
から行う必要があります。コールバック パラメータに加えて、含まれるアクティビティまたはフラグメントと、MapView
の構成属性を含む null の GoogleMapOptions
が必要です。アクティビティまたはフラグメントの基本クラスは、それぞれライフサイクルへのアクセスを提供するため、FragmentActivity
またはサポート Fragment
のいずれかである必要があります。
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,
)
}
}
フラグメントの MapView
は、アクティビティ内の上記の MapView
の例と同じですが、フラグメントの onCreateView()
メソッドに MapView
を含むレイアウトがインフレートする点が異なります。
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)
}
}
旅路に合わせてカメラのズームを調整する
Maps SDK に組み込まれているデフォルトの現在地ボタンでは、デバイスの現在地がカメラの中央に配置されます。
アクティブなジャーニー共有セッションがある場合は、デバイスの位置情報ではなく、ジャーニーにカメラを向けることをおすすめします。
一般ユーザー向け SDK for Android 組み込みソリューション: AutoCamera
そのため、デバイスの位置情報ではなく、操作に集中できるように、Consumer SDK には、デフォルトで有効になっている AutoCamera 機能が用意されています。移動経路と次のルートの地点にズームしてズームします。
カメラの動作をカスタマイズする
カメラの動作をより詳細に制御する必要がある場合は、ConsumerController.setAutoCameraEnabled() を使用して自動カメラを有効または無効にできます。
ConsumerController.getCameraUpdate() は、その時点における推奨カメラ境界を返します。この CameraUpdate
を引数として GoogleMap.moveCamera() または GoogleMap.animateCamera() に指定できます。
ライドシェアリングと地図にアクセス
アプリでライドシェアリングと地図操作をサポートするには、ConsumerGoogleMap
と ConsumerController
へのアクセス権が必要です。ConsumerMapFragment
と ConsumerMapView
はどちらも ConsumerMapReadyCallback
で非同期に ConsumerGoogleMap
を返します。ConsumerGoogleMap
は、getConsumerController()
から ConsumerController
を返します。ConsumerGoogleMap
と ConsumerController
には、次のようにアクセスできます。
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,
}
)
コンシューマ Google マップ
ConsumerGoogleMap
は GoogleMap
クラスのラッパークラスです。これにより、アプリは GoogleMap
と同等の API を使用して地図を操作できるようになります。コンシューマ マップを使用すると、アプリと配車サービスが同じ基盤となる Google マップとシームレスにやり取りできます。たとえば、GoogleMap
は 1 つのコールバック登録のみを許可しますが、ConsumerGoogleMap
はデュアル登録されたコールバックをサポートします。これらのコールバックを使用すると、アプリとライドシェアリングで、順次に呼び出されるコールバックを登録できます。
コンシューマ コントローラ
ConsumerController
では、ルートのモニタリング、ルートのステータスの管理、位置情報の設定など、ライドシェアリング機能を利用できます。
経路の共有を設定する
バックエンドが自動車とユーザーをマッチングしたら、JourneySharingSession
を使用してユーザー インターフェースの共有を開始します。移動経路を共有すると、一致する車両の位置情報とルートが表示されます。アプリに SDK を実装すると、ルートのモニタリング、更新のリッスン、エラーの処理のための機能を追加できます。次の手順では、バックエンド サービスが実行されており、消費者と車両をマッチングするためのサービスが稼働していることを前提としています。
TripModel
オブジェクトにリスナーを登録して、到着予定時刻や到着前に車両が移動する必要のある距離など、ルートの詳細情報を取得します。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?, ) { // ... } // ... })
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)
ジャーニーの共有を停止
ホスト アクティビティが破棄された場合など、不要になった共有の停止は停止してください。プロセスの共有を停止すると、Fleet Engine へのネットワーク リクエストも停止し、メモリリークを防止できます。
次のサンプルコードは、ジャーニーの共有を停止する方法を示しています。
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()
}
}
ルートエラーの処理
onTripRefreshError
メソッドは、ルートのモニタリング中に発生したエラーを表示します。コンシューマ SDK エラーのマッピングは、Google Cloud Platform で確立されているものと同じ HTTP/RPC ガイドラインに従います。ルート モニタリング中に表示される一般的なエラーには、次のようなものがあります。
HTTP | RPC | 説明 |
---|---|---|
400 | INVALID_ARGUMENT | 顧客が無効なルート名を指定しました。トリップ名は providers/{provider_id}/trips/{trip_id} の形式にする必要があります。provider_id は、サービス プロバイダが所有する Cloud プロジェクトの ID にする必要があります。 |
401 | 未認証 | JWT トークンが無効なため、リクエストが認証されていません。このエラーは、JWT トークンがトリップ ID なしで署名されているか、JWT トークンの有効期限が切れている場合に発生します。 |
403 | PERMISSION_DENIED(実行拒否) | クライアントに十分な権限がありません。このエラーは、JWT トークンが無効、クライアントに権限がない、またはクライアント プロジェクトで API が有効になっていない場合に発生します。JWT トークンが不足しているか、トークンが、リクエストされたルート ID と一致しないルート ID で署名されている可能性があります。 |
429 | RESOURCE_EXHAUSTED | リソースの割り当てがゼロであるか、トラフィック率が上限を超えています。 |
503 | 使用不可 | サービス利用不可。通常、サーバーはダウンしています。 |
504 | DEADLINE_EXCEEDED(期限超過) | リクエスト期限を超えました。これは、呼び出し元がメソッドのデフォルトの期限よりも短い期限を設定している場合(つまり、要求された期限がサーバーでリクエストを処理するのに十分な量ではない場合)、リクエストが期限内に完了しなかった場合にのみ発生します。 |
詳細については、Consumer SDK のエラー処理をご覧ください。