ルートを追跡すると、適切な車両の位置情報がコンシューマ アプリに表示されます。これを行うには、アプリでルートの追跡を開始し、ルートの進行状況を更新し、ルートの完了時にルートの追跡を停止する必要があります。
このドキュメントでは、そのプロセスの仕組みについて説明します。
始める前に
次のものが設定されていることを確認します。
コンシューマ アプリのバックエンド サービスが設定され、コンシューマと車両を照合するサービスが動作している。
アプリに地図を設定している。
ルート案内のフォローを開始する
バックエンド サーバーがコンシューマと車両を照合したら、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 | サーバーが利用できなかった。これは通常、ネットワークの問題が原因で発生します。 |
クライアントエラー
次のステータス コードはクライアント エラーであり、解決するには対応する必要があります。ユーザー SDK は、ルートの共有を終了するまでルートの更新を再試行し続けますが、ユーザーが操作を行うまで復元されません。
ステータス コード | 説明 |
---|---|
INVALID_ARGUMENT | コンシューマ アプリで無効なルート名が指定されています。ルート名は providers/{provider_id}/trips/{trip_id} の形式にする必要があります。 |
NOT_FOUND | 旅行が作成されなかった。 |
PERMISSION_DENIED | コンシューマ アプリに十分な権限がありません。このエラーは、次の場合に発生します。
|
RESOURCE_EXHAUSTED | リソース割り当てがゼロであるか、トラフィック フローのレートが制限速度を超えている。 |
UNAUTHENTICATED | JWT トークンが無効なため、リクエストの認証に失敗しました。このエラーは、JWT トークンがルート ID なしで署名されている場合、または JWT トークンの有効期限が切れている場合に発生します。 |