トリップを追跡すると、ユーザーアプリに適切な車両の位置が表示されます。これを行うには、アプリでトリップの追跡を開始し、トリップの進行状況を更新して、トリップが完了したらトリップの追跡を停止する必要があります。
このドキュメントでは、そのプロセスの仕組みについて説明します。
始める前に
次のものが設定されていることを確認します。
ユーザーアプリのバックエンド サービスが配置され、ユーザーと車両をマッチングするサービスが稼働している。
アプリに地図を設定している。
ルートのフォローを開始する
バックエンド サーバーがユーザーと車両をマッチングしたら、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 は、コールバック メカニズムを使用して、トリップの更新エラーをユーザーアプリに送信します。コールバック パラメータは、プラットフォーム固有の戻り値の型(Android では TripUpdateError、iOS では NSError)です。
ステータス コードを抽出する
コールバックに渡されるエラーは通常、gRPC エラーです。ステータス コードの形式で追加情報を抽出することもできます。ステータス コードの完全なリストについては、ステータス コードと gRPC での使用をご覧ください。
Java
onTripUpdateError() から返された TripUpdateError から、エラーの詳細を示す gRPC ステータス コードを抽出できます。
// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
Status.Code code = error.getStatusCode();
}
Kotlin
onTripUpdateError() から返された TripUpdateError から、エラーの詳細を示す gRPC ステータス コードを抽出できます。
// 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 トークンの有効期限が切れている場合に発生します。 |