Android でルートをフォローする

プラットフォームを選択: Android iOS JavaScript

ルートを追跡すると、一般ユーザー向けアプリに 適切な車両を判断できますこれを行うには、アプリでルートの追跡を開始し、ルートの進行状況を更新し、ルートの完了時にルートの追跡を停止する必要があります。

このドキュメントでは、そのプロセスについて説明します。

始める前に

以下の項目が設定されていることを確認してください。

  • 一般ユーザー向けアプリのバックエンド サービスが導入されており、サービスが用意されている いくつかのプロダクトを提供しています

  • アプリの地図を設定している。

ルートのフォローを開始する

バックエンド サーバーで消費者と車両を照合する場合は、 移動経路の共有を使用してルートのフォローを開始するには、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()
  }
}

移動状況を更新

車両に必要な距離など、移動状況の詳細を更新する 推定到着時刻を予測する場合、アプリは 次の例に示すように、リスナーを登録して設定します。

  1. 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?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. 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)
    

旅行のフォローを停止する

ルートのフォローが不要になった場合、アプリによるルートのフォローを ルートが運転手によってバックエンドで COMPLETE とマークされたものと見なします。停止中のプロセス 共有により、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 と一致しません。
429 RESOURCE_EXHAUSTED リソースの割り当てがゼロであるか、トラフィックのレートが上限を超えています。
503 UNAVAILABLE サービス利用不可。通常、サーバーがダウンしています。
504 DEADLINE_EXCEEDED リクエスト期限を超えました。このエラーは、呼び出し元が メソッドのデフォルトの期限(つまり、 サーバーがリクエストを処理するには、要求された期限では足りません)。 期限内にリクエストが完了しませんでした。

Consumer SDK エラーを処理する

Consumer SDK は、コールバック メカニズムを使用して、ルートの更新エラーをコンシューマ アプリに送信します。コールバック パラメータはプラットフォーム固有の戻り値の型( TripUpdateErrorNSError

ステータス コードを抽出する

通常、コールバックに渡されるエラーは 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()
}

ステータス コードを解釈する

ステータス コードは、サーバーおよびネットワーク関連のエラーと、 クライアントサイドのエラーです。

サーバー エラーとネットワーク エラー

次のステータス コードはネットワーク エラーまたはサーバー エラーであり、解決するための対応は必要ありません。Consumer SDK が自動的に 復元します。

ステータス コード説明
ABORTED サーバーがレスポンスの送信を停止しました。この問題は通常 発生します。
CANCELLED サーバーが送信レスポンスを終了しました。これは通常、
アプリがバックグラウンドに送信されたとき、または
コンシューマ アプリの状態が変更されたときに発生します。
INTERRUPTED
DEADLINE_EXCEEDED サーバーの応答に時間がかかりすぎました。
UNAVAILABLE サーバーにアクセスできませんでした。これは通常、ネットワークや 困難です。

クライアントエラー

次のステータス コードはクライアント エラーを示します。 解決できます。Consumer SDK はルートの更新を再試行し続けます。 履歴の共有は終了しますが 復元はできません

ステータス コード説明
INVALID_ARGUMENT ユーザー アプリが指定したルート名が無効です。旅行名は providers/{provider_id}/trips/{trip_id} の形式に従います。
NOT_FOUND ルートが作成されない。
PERMISSION_DENIED コンシューマ アプリに十分な権限がありません。このエラーは、次の場合に発生します。
<ph type="x-smartling-placeholder">
    </ph>
  • ユーザー アプリに権限がない
  • Google Cloud コンソールで、プロジェクトで Consumer SDK が有効になっていません。
  • JWT トークンがないか、無効です。
  • JWT トークンが、リクエストされたルートとは異なるルート ID で署名されている。
RESOURCE_EXHAUSTED リソース割り当てがゼロであるか、トラフィック フローのレートが 制限します。
UNAUTHENTICATED JWT トークンが無効なため、リクエストが認証に失敗しました。この JWT トークンがルート ID なしで署名された場合、または JWT トークンの有効期限が切れたとき。