ルートをフォローすると、ユーザーアプリに適切な車両の位置が表示されます。そのため、アプリはルートのフォローを開始し、ルートの進行状況を更新し、ルートが完了したらフォローを停止する必要があります。
このドキュメントでは、そのプロセスの仕組みについて説明します。
始める前に
次のことを確認してください。
ユーザーアプリのバックエンド サービスが設定され、コンシューマーと車両をマッチングするサービスが稼働している。
アプリの地図を設定している。
ルートのフォローを開始する
バックエンド サーバーがコンシューマーと車両をマッチングしたら、JourneySharingSession を使用してルートのフォローを開始します。
次のサンプルコードは、ビューの読み込み後にルートのフォローを開始する方法を示しています。
Java
public class MainActivity extends AppCompatActivity
implements ConsumerViewModel.JourneySharingListener {
// Class implementation
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a TripModel instance to listen for 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) {
// ...
}
// ...
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (journeySharingSession != null) {
journeySharingSession.stop();
}
}
}
Kotlin
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
// Class implementation
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create a TripModel instance to listen for 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?,
) {
// ...
}
// ...
})
}
override fun onDestroy() {
super.onDestroy()
journeySharingSession?.stop()
}
}
ルートの進行状況を更新する
ルートの進行状況の詳細(到着までに車両が走行する必要がある距離や予定到着時刻など)を更新するには、次の例に示すように、アプリでリスナーを登録して構成する必要があります。
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 への不要なネットワーク リクエストを回避し、メモリリークを防ぐことができます。
次のサンプルコードに示すように、JourneySharingSession を使用してルートのフォローを停止します。
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 メソッドは、ルートのモニタリング中に発生したエラーを表示します。エラー メッセージは Google Cloud エラー標準に準拠しています。エラー メッセージの定義とすべてのエラーコードについて詳しくは、Google Cloud エラー
のドキュメントをご覧ください。
ルートのモニタリング中に発生する一般的なエラーをいくつか示します。
| HTTP | RPC | 説明 |
|---|---|---|
| 400 | INVALID_ARGUMENT | クライアントが無効なルート名を指定しました。ルート名は
形式 providers/{provider_id}/trips/{trip_id} に従う必要があります。
provider_id は、サービス プロバイダが所有する Cloud プロジェクトの ID である必要があります。 |
| 401 | UNAUTHENTICATED | 有効な認証情報がない場合にこのエラーが発生します。 たとえば、JWT トークンがルート ID なしで署名されている場合や、JWT トークン の有効期限が切れている場合などです。 |
| 403 | PERMISSION_DENIED | クライアントに十分な権限がない場合 (コンシューマー ロールのユーザーが updateTrip を呼び出そうとした場合など)、JWT トークンが無効な場合、またはクライアント プロジェクトで API が有効になっていない場合に、このエラーが発生します。 JWT トークンがないか、リクエストされたルート ID と一致しないルート ID でトークンが署名されている可能性があります。 |
| 429 | RESOURCE_EXHAUSTED | リソース割り当てがゼロであるか、トラフィック レートが上限を超えています。 |
| 503 | UNAVAILABLE | サービス利用不可。通常、サーバーがダウンしています。 |
| 504 | DEADLINE_EXCEEDED | リクエスト期限を超えました。このエラーは、呼び出し元が、メソッドのデフォルト期限よりも短い期限を設定し(つまり、 要求された期限はサーバーがリクエストを処理するのに十分ではない)、 リクエストがその期限内に完了しなかった場合にのみ発生します。 |
Consumer SDK のエラーを処理する
Consumer SDK は、コールバック メカニズムを使用して、ルートの更新エラーをユーザーアプリに送信します。コールバック パラメータは、プラットフォーム固有の戻り値の型(
TripUpdateError
Android の場合、
NSError
iOS の場合)です。
ステータス コードを抽出する
コールバックに渡されるエラーは通常 gRPC エラーであり、ステータス コードの形式で追加情報を抽出することもできます。ステータス コードの 完全なリストについては、 gRPC でのステータス コードとその使用をご覧ください。
Java
エラーの詳細を示す gRPC ステータス コードを、TripUpdateError から返された onTripUpdateError() から抽出できます
。
// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
Status.Code code = error.getStatusCode();
}
Kotlin
エラーの詳細を示す gRPC ステータス コードを、TripUpdateError から返された onTripUpdateError() から抽出できます
。
// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
val code = error.getStatusCode()
}
ステータス コードを解釈する
ステータス コードは、サーバーとネットワーク関連のエラーとクライアントサイドのエラーの 2 種類のエラーをカバーします。
サーバーとネットワークのエラー
次のステータス コードは、ネットワーク エラーまたはサーバーエラーを示します。これらのエラーを解決するための対応は必要ありません。Consumer SDK は自動的に復旧します。
| ステータス コード | 説明 |
|---|---|
| ABORTED | サーバーがレスポンスの送信を停止しました。通常、これは サーバーの問題が原因です。 |
| CANCELLED | サーバーが送信レスポンスを終了しました。通常、これはアプリがバックグラウンドに送信された場合、またはユーザーアプリの状態が変更された場合に発生します。 |
| INTERRUPTED | |
| DEADLINE_EXCEEDED | サーバーからの応答に時間がかかりすぎました。 |
| UNAVAILABLE | サーバーが利用できませんでした。通常、これはネットワーク の問題が原因です。 |
クライアントエラー
次のステータス コードはクライアント エラーを示します。これらのエラーを解決するには対応が必要です。Consumer SDK は、ルートの共有を終了するまでルートの更新を再試行しますが、対応するまで復旧しません。
| ステータス コード | 説明 |
|---|---|
| INVALID_ARGUMENT | ユーザーアプリが無効なルート名を指定しました。ルート名は
providers/{provider_id}/trips/{trip_id} の形式にする必要があります。 |
| NOT_FOUND | ルートが作成されていません。 |
| PERMISSION_DENIED | ユーザーアプリに十分な権限がありません。このエラーは、次の場合に発生します。
|
| RESOURCE_EXHAUSTED | リソース割り当てがゼロであるか、トラフィック フローのレートが 速度制限を超えています。 |
| UNAUTHENTICATED | 無効な JWT トークンが原因でリクエストの認証に失敗しました。この エラーは、JWT トークンがルート ID なしで署名されている場合、または JWT トークンの有効期限が切れている場合に発生します。 |