ラスト ワンマイルのフリート ソリューションは現在、一部のお客様のみご利用いただけます。詳しくは、営業担当者までお問い合わせください。

Driver SDK for Android のスタートガイド

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

最小システム要件

モバイル デバイスが Android 5.0(API レベル 21)以降を実行している。

Prerequisites

このガイドでは、アプリに Navigation SDK がすでに実装され、Fleet Engine バックエンドが設定され、利用可能であることを前提としています。

Driver SDK for Android が 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.0</version>
      </extension>
    </extensions>
  </build>

アクセスの確認については、Java パッケージの管理をご覧ください。

プロジェクト構成

Driver SDK を使用するには、アプリで minSdkVersion 21 以降をターゲットにする必要があります。詳細については、リリースノートをご覧ください。

Driver SDK を使用してビルドされたアプリを実行するには、Android デバイスに Google Play 開発者サービスがインストールされている必要があります。

開発プロジェクトを設定する

開発プロジェクトを設定して、Google Cloud Console でプロジェクトの API キーを取得するには:

  1. Driver SDK で使用できるように、新しい Google Cloud Console プロジェクトを作成するか、既存のプロジェクトを選択します。新しいプロジェクトが Google Cloud Console に表示されるまで数分待ちます。

  2. デモアプリを実行するには、プロジェクトに Maps SDK for Android へのアクセス権が付与されている必要があります。Google Cloud Console で、[API とサービス] > [ライブラリ] を選択し、Maps SDK for Android を検索して有効にします。

  3. プロジェクトの API キーを取得するには、[API とサービス] > [認証情報] > [認証情報を作成] > [API キー] を選択します。API キーの取得について詳しくは、API キーを取得するをご覧ください。

アプリに Driver SDK を追加する

Driver SDK は非公開の Maven リポジトリから入手できます。リポジトリには、SDK の Project Object Model(.pom)ファイルと Javadocs が含まれています。Driver SDK をアプリに追加するには:

  1. 構成セクションの説明に沿って、ホスト Maven リポジトリにアクセスするように環境を設定します。

  2. Gradle または Maven 構成に次の依存関係を追加します。VERSION_NUMBER プレースホルダは、目的のドライバ用ドライバの SDK のバージョンに置き換えてください。

    Gradle

    build.gradle に次の行を追加します。

    dependencies {
      ...
      implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:[VERSION_NUMBER]'
    }
    

    Maven

    pom.xml に次の行を追加します。

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation.driver</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>[VERSION_NUMBER]</version>
      </dependency>
    </dependencies>
    

アプリに API キーを追加する

Driver SDK をアプリに追加したら、API キーをアプリに追加します。開発プロジェクトを設定したときに取得したプロジェクト API キーを使用する必要があります。

このセクションでは、アプリでより安全に参照できるように API キーを保存する方法について説明します。API キーをバージョン管理システムにチェックインしないでください。これは、プロジェクトのルート ディレクトリにある local.properties ファイルに保存する必要があります。local.properties ファイルの詳細については、Gradle プロパティ ファイルをご覧ください。

このタスクを効率化するには、Android 用 Secrets Gradle プラグインを使用します。Secrets Gradle プラグインをインストールして、API キーを安全に保存する手順は次のとおりです。

  1. ルートレベルの 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")
        }
    }
    
  2. アプリレベルの build.gradle ファイルを開き、次のコードを plugins 要素に追加します。

    Groovy

    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. プロジェクトを Gradle と同期する

  4. プロジェクト レベルのディレクトリで local.properties を開き、次のコードを追加します。YOUR_API_KEY は実際の API キーに置き換えてください。

    MAPS_API_KEY=YOUR_API_KEY
    
  5. 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.driverapidemo" >
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_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>

必須の帰属情報をアプリに含める

アプリで Driver SDK を使用する場合は、アプリの法的通知セクションの一部として、アトリビューション テキストとオープンソース ライセンスを含める必要があります。アトリビューションは、独立したメニュー項目として、または [概要] メニュー項目の一部として含めることをおすすめします。

必要なアトリビューション テキストとオープンソース ライセンスは、Driver SDK の zip ファイルで確認できます。

  • NOTICE.txt
  • LICENSES.txt

依存関係

Driver SDK は gRPC を使用して Fleet Engine サーバーと通信します。gRPC をまだインポートしていない場合は、次の依存関係を宣言する必要があります。

dependencies {
    implementation 'io.grpc:grpc-android:1.12.0'
    implementation 'io.grpc:grpc-okhttp:1.12.0'
}

これらの依存関係がないと、ドライバ SDK が Fleet Engine サーバーとの通信を試行すると、実行時にエラーが発生します。

ProGuard を使用してビルドを最適化する場合は、ProGuard 構成ファイルに次の行を追加する必要があります。

-dontwarn com.google.**
-dontwarn io.grpc.**
-dontwarn okio.**

サポートされる最小 API レベルは 21 です。

SDK の初期化

DriverContext オブジェクトを初期化するには、プロバイダ ID(通常は Google Cloud プロジェクト ID)が必要です。Google Cloud プロジェクトの設定の詳細については、認証と認可をご覧ください。

Driver SDK を使用する前に、Navigation SDK を初期化する必要があります。SDK を初期化するには:

  1. NavigationApi から Navigator オブジェクトを取得します。

    NavigationApi.getNavigator(
        this, // Activity
        new NavigationApi.NavigatorListener() {
          @Override
          public void onNavigatorReady(Navigator navigator) {
            // Keep a reference to the Navigator (used to configure and start nav)
            this.navigator = navigator;
          }
        }
    );
    
  2. DriverContext オブジェクトを作成し、必須項目に入力します。

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    
  3. DriverContext オブジェクトを使用して *DriverApi を初期化します。

    DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
    
  4. API オブジェクトから DeliveryVehicleReporter を取得します。(DeliveryVehicleReporterNavigationVehicleReporter を拡張します)。

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

AuthTokenFactory による認証

Driver SDK が位置情報の更新を生成したら、これらの更新を Fleet Engine サーバーに送信する必要があります。これらのリクエストを認証するために、Driver SDK は呼び出し元が提供する AuthTokenFactory のインスタンスを呼び出します。工場では、位置情報の更新時に認証トークンを生成します。

生成されるトークンはデベロッパーごとに異なります。ただし、実装で次のことが必要となる可能性があります。

  • HTTPS サーバーから認証トークン(JSON 形式の可能性あり)を取得します。
  • トークンを解析してキャッシュに保存する
  • 有効期限が切れたらトークンを更新する

Fleet Engine サーバーで想定されるトークンの詳細については、認可用の JSON ウェブトークン(JWT)の作成をご覧ください。

AuthTokenFactory のスケルトン実装を次に示します。

class JsonAuthTokenFactory implements AuthTokenFactory {
  private String vehicleServiceToken;  // initially null
  private long expiryTimeMs = 0;

  // This method is called on a thread whose only responsibility is to send
  // location updates. Blocking is OK, but just know that no location updates
  // can occur until this method returns.
  @Override
  public String getToken(AuthTokenContext authTokenContext) {
    if (System.currentTimeMillis() > expiryTimeMs) {
      // The token has expired, go get a new one.
      fetchNewToken(vehicleId);
    }
    if (ServiceType.VEHICLE.equals(authTokenContext.getServiceType)) {
      return vehicleServiceToken;
    } else {
      throw new RuntimeException("Unsupported ServiceType: " + authTokenContext.getServiceType());
    }
  }

  private void fetchNewToken(String vehicleId) {
    String url = "https://yourauthserver.example/token/" + vehicleId;

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
      vehicleServiceToken = obj.get("VehicleServiceToken").getAsString();
      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 10 minutes from that time.
      expiryTimeMs -= 10 * 60 * 1000;
    } catch (IOException e) {
      // It's OK to throw exceptions here. The StatusListener you passed to
      // create the DriverContext class will be notified and passed along the failed
      // update warning.
      throw new RuntimeException("Could not get auth token", e);
    }
  }
}

この実装では、組み込みの Java HTTP クライアントを使用して、デベロッパーの認証サーバーから JSON 形式のトークンを取得します。トークンは再利用のために保存されます。トークンは、有効期限の 10 分以内に古いトークンが再取得されます。

実装によっては、トークンの更新にバックグラウンド スレッドを使用するなど、別の動作をすることもあります。

AuthTokenFactory で例外が繰り返されない限り、例外は一時的なものとして扱われます。ドライバ SDK では何度か試行した後、エラーが永続的であると想定し、更新の送信を停止します。

StatusListener でのステータスと Error Reporting

Driver SDK はバックグラウンドでアクションを実行するため、StatusListener を使用して、エラー、警告、デバッグ メッセージなどの特定のイベントが発生したときに通知をトリガーします。エラーは性質上(BACKEND_CONNECTIVITY_ERROR など)に発生することがあります。また、位置情報の更新が恒久的に停止する(VEHICLE_NOT_FOUND など)ことで構成エラーが発生することがあります。

次のような StatusListener の実装(省略可)を指定します。

class MyStatusListener implements StatusListener {
  /** Called when background status is updated, during actions such as location reporting. */
  @Override
  public void updateStatus(
      StatusLevel statusLevel, StatusCode statusCode, String statusMsg) {
    // Status handling stuff goes here.
    // StatusLevel may be DEBUG, INFO, WARNING, or ERROR.
    // StatusCode may be DEFAULT, UNKNOWN_ERROR, VEHICLE_NOT_FOUND,
    // BACKEND_CONNECTIVITY_ERROR, or PERMISSION_DENIED.
  }
}

SSL/TLS に関する注意事項

内部的には、Driver SDK の実装は SSL/TLS を使用して Fleet Engine サーバーと安全に通信します。古いバージョンの Android(API バージョン 21 以前)では、サーバーと通信するために SecurityProvider パッチが必要になる場合があります。Android での SSL の操作について詳しくは、こちらの記事をご覧ください。この記事では、セキュリティ プロバイダにパッチを適用するためのコードサンプルについても説明します。

位置情報の更新を有効にする

*VehicleReporter インスタンスを取得すると、位置情報の更新の有効化は簡単です。

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

位置情報の更新は、可能であれば定期的に送信されます。また、位置情報が更新されるたびに、車両がオンラインになっていることも示されます。

デフォルトでは、レポート間隔は 10 秒です。レポート間隔は reporter.setLocationReportingInterval(long, TimeUnit) で変更できます。サポートされている最小更新間隔は 5 秒です。更新を頻繁に行うと、リクエストやエラーの処理が遅くなる可能性があります。

位置情報の更新を無効にする

ドライバーのシフトが終了したら、DeliveryVehicleReporter.disableLocationTracking を呼び出して位置情報の更新を停止できます。

信頼できるモデルのユースケース

このセクションでは、信頼できるモデルを使用する際に Driver SDK を使用して一般的なユースケースを実装する方法について説明します。

車両の作成

Driver SDK から車両を作成できます。

車両を作成する前に、Delivery Driver API を初期化してください。車両 ID は、Driver SDK の初期化中に使用する車両とプロバイダ ID を使用して作成する必要があります。次に、次の例のように車両を作成します。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleManager vehicleManager = api.getDeliveryVehicleManager();
try {
  DeliveryVehicle vehicle = vehicleManager.createVehicle().get();
  // Handle CreateVehicleRequest DeliveryVehicle response.
} catch (Exception e) {
  // Handle CreateVehicleRequest error.
}

集荷タスクを作成する

Driver SDK から配送の受け取りタスクを作成できます。

タスクを作成する前に、Delivery Driver API を初期化してください。このタスクは、Driver SDK の初期化時に指定されたプロバイダ ID を使用して作成する必要があります。次に、次の例のように集荷タスクを作成します。タスク ID の詳細については、タスク ID の例をご覧ください。

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
   .setTaskDurationSeconds(2 * 60)
   .setParentId("my-tracking-id")
   .setTaskType(TaskType.DELIVERY_PICKUP)
   .build();

try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

配送タスクの作成

配送タスクは Driver SDK から作成できます。

タスクを作成する前に、Delivery Driver API を初期化してください。次に、次の例のように配送タスクを作成します。 タスク ID の詳細については、タスク ID の例をご覧ください。

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
   .setTaskDurationSeconds(2 * 60)
   .setParentId("my-tracking-id")
   .setTaskType(TaskType.DELIVERY_DELIVERY)
   .build();
try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

予約不可

Driver SDK から利用できないことを示すタスク(ドライバーの休憩や燃料の補充など)を作成できます。スケジュール不可のタスクにトラッキング ID を含めることはできません。必要に応じて、場所を指定することもできます。

タスクを作成する前に、Delivery Driver API を初期化してください。次に、次の例のように、利用できないタスクを作成します。 タスク ID の詳細については、タスク ID の例をご覧ください。

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setTaskDurationSeconds(2 * 60) // Duration or location (or both) must be provided for a BREAK task.
   .setTaskType(TaskType.UNAVAILABLE)
   .build();
try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

予定がある停留所

スケジュールされた停止タスクは、Driver SDK から作成できます。スケジュール設定された停止タスクに、トラッキング ID が含まれていないことがあります。

タスクを作成する前に、Delivery Driver API を初期化してください。次に、次の例に示すように、スケジュールされた停止タスクを作成します。タスク ID の詳細については、タスク ID の例をご覧ください。

static final String TASK_ID = "task-8241890"; //  Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
   .setTaskDurationSeconds(2 * 60)
   .setTaskType(TaskType.DELIVERY_SCHEDULED_STOP)
   .build();
try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

タスクの順序の更新

車両に割り当てられたタスクの実行順序は Driver SDK から更新できます。

タスクの割り当てを更新すると、以前に車両に割り当てられていなかった場合に、車両にもタスクが割り当てられます。また、以前に車両に割り当てられ、更新された注文から除外されたタスクも終了します。以前に別の車両に割り当てられていたタスクを別の車両に割り当てると、エラーが発生します。新しい車両にタスクを割り当てる前に、既存のタスクを閉じてから新しいタスクを作成します。

タスクの順番はいつでも更新できます。

車両のタスクの順序を更新する前に、車両とタスクが Fleet Engine に作成されていることを確認します。次に、車両のタスクの順序を更新します。次に例を示します。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
try {
   List<VehicleStop> stops = reporter.setVehicleStops(
     ImmutableList.of(
         VehicleStop.builder()
             .setVehicleStopState(VehicleStopState.ARRIVED)
             .setWaypoint(Waypoint.builder().setLatLng(37.1749, 122.412).build())
             .setTasks(ImmutableList.of(task1)) // Previously created DeliveryTask in Fleet Engine.
             .build(),
         VehicleStop.builder()
             .setVehicleStopState(VehicleStopState.NEW) // The current vehicle stop.
             .setWaypoint(Waypoint.builder().setLatLng(37.7749, 122.4194).build())
             .setTasks(ImmutableList.of(task2)) // Previously created DeliveryTask in Fleet Engine.
             .build(),
         VehicleStop.builder()
             .setVehicleStopState(VehicleStopState.NEW)
             .setWaypoint(Waypoint.builder().setLatLng(37.3382, 121.8863).build())
             .setTasks(ImmutableList.of(task3, task4)) // Previously created DeliveryTasks in Fleet Engine.
             .build())).get();
   // Successfully updated vehicle stops in Fleet Engine. Returns the successfully set VehicleStops.
} catch (Exception e)  {
   // Failed to update vehicle stops in Fleet Engine. Setting VehicleStops must be attempted again after resolving
   // errors.
}

例外により、Driver SDK の内部状態が更新されない可能性があります。この場合は、問題を解決してから、呼び出しが成功するまで setVehicleStops を再度呼び出します。

次のような問題が考えられます。

  • 指定された VehicleStop は有効なパターンに従っていません。最初の VehicleStop は、VehicleStopState のいずれか(NEW、ENROUTE、ARRIVED)のいずれかになります。現在の停車地の後の VehicleStop は、新しい VehicleStopState である必要があります。

  • タスクが存在しないか、別の車両に属しています。

  • 車両が存在しません。

次の目的地まで車が案内中

車両が停車地から出発したときと、ナビが始まったときに、Fleet Engine に通知する必要があります。Driver SDK から Fleet Engine に通知することもできます。

車両が停車地から出発したことを Fleet Engine に通知する前に、車両の停止が作成され、設定されていることを確認してください。その後、次の例のように、車両の出発を Fleet Engine に通知します。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
reporter.enableLocationTracking(); // Location tracking must be enabled.

// Create Vehicle, VehicleStops, and DeliveryTasks.
// Set VehicleStops on Vehicle.

navigator.setDestination(vehicleStop.getWaypoint());
try {
   List<VehicleStop> updatedStops = reporter.enrouteToNextStop().get();
   // Successfully updated vehicle stops in Fleet Engine. Returns the set VehicleStops, with the first
   // VehicleStop updated to ENROUTE state.
} catch (Exception e)  {
   // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
   // after resolving errors.
}

例外により、Driver SDK の内部状態が更新されない可能性があります。この場合は、問題を解決してから、正常に完了するまで enrouteToNextStop を再度呼び出してください。

次のような問題が考えられます。

  • Driver SDK で残りの VehicleStops が設定されていません。

車両が停留所に到着

車両が停車地に到着したら、Fleet Engine に通知する必要があります。Driver SDK から Fleet Engine に通知することもできます。

車両が停車地に到着したことを Fleet Engine に通知する前に、車両の停止が設定されていることを確認してください。次に、車両が停車地に到着することを Fleet Engine に通知します。次に例を示します。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
reporter.enableLocationTracking(); // Location tracking must be enabled.

// Create Vehicle, VehicleStops, and DeliveryTasks.
// Set VehicleStops on Vehicle.
// Mark ENROUTE to VehicleStop and start guidance using Navigator.

try {
   List<VehicleStop> updatedStopsArrived = reporter.arrivedAtStop().get();
   // Successfully updated vehicle stops in Fleet Engine. Returns the set VehicleStops, with the first
   // VehicleStop updated to ARRIVED state.
   navigator.clearDestinations();
} catch (Exception e)  {
   // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
   // after resolving errors.
}

例外により、Driver SDK の内部状態が更新されない可能性があります。この場合は、問題を解決してから、正常に完了するまで arrivedAtStop を再度呼び出します。

次のような問題が考えられます。

  • Driver SDK で残りの VehicleStops が設定されていません。

車両の停止

車両の停止が完了したときに、Fleet Engine に通知する必要があります。これにより、その停車地に関連付けられているすべてのタスクが CLOSED 状態に設定されます。ドライバ SDK から Fleet Engine に通知することもできます。

次の例に示すように、車両の VehicleStop が完了したことを Fleet Engine に通知します。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
reporter.enableLocationTracking(); // Location tracking must be enabled.

// After completing the tasks at the VehicleStop, remove it from the
// the current list of VehicleStops.

try {
   List<VehicleStop> updatedStopsCompleted = reporter.completedStop().get();
   // Successfully updated vehicle stops in Fleet Engine. All tasks on the completed stop are set to CLOSED.
   // Returns the set VehicleStops, with the completed VehicleStop removed from the remaining list.
} catch (Exception e)  {
   // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
   // after resolving errors.
}

例外により、Driver SDK の内部状態が更新されない可能性があります。この場合は、問題を解決してから、正常に完了するまで completedStop を再度呼び出します。

次のような問題が考えられます。

  • Driver SDK で残りの VehicleStops が設定されていません。

タスクを閉じる

車両に割り当てられているタスクを閉じるには、タスクが行われる停車地が完了したことを Fleet Engine に通知するか、車両停止のリストから削除します。これを行うには、車両のタスクの順序を更新するときと同様に、残りの車両停止のリストを設定します。

タスクに車両がまだ割り当てられておらず、タスクを終了する必要がある場合は、タスクを CLOSED の状態に更新します。ただし、CLOSED タスクを再開することはできません。

タスクを閉じても、成功または失敗を示すわけではありません。これは、タスクが進行中とみなされなくなったことを示します。配送の追跡では、配送の結果を表示できるように、タスクの実際の結果を示すことが重要です。

Driver SDK を使用してタスクを閉じるには、タスクを車両に割り当てる必要があります。車両に割り当てられているタスクを閉じるには、タスクが行われる停車地で車両が完了したことをフリート エンジンに通知します。

または、タスクが割り当てられている車両のタスクの順序を更新し、停車地のリストから目的のタスクを削除します。

タスクの結果と結果のロケーションを設定する

タスクを閉じても、成功または失敗を示すわけではありません。これは、タスクが進行中とみなされなくなったことを示します。配送の追跡では、タスクの実際の結果を示し、配送結果を表示して、サービスに適切な課金が行われるようにすることが重要です。設定後にタスクの結果を変更することはできません。ただし、タスクの結果時間とタスク結果のロケーションは、設定後に変更できます。

CLOSED 状態のタスクでは、結果に SUCCEEDED または FAILED を設定できます。ステータスが SUCCEEDED の集荷タスクと配送タスクのみが請求されます。

タスクの結果にマークを付けると、Fleet Engine はタスクの結果にある位置情報を、最後に確認された車両位置情報に自動的に入力します。この動作はオーバーライドできます。

次の例は、Driver SDK を使用してタスクの結果とタイムスタンプを設定する方法を示しています。Driver SDK を使用してタスクの結果の場所を設定することはできません。

static final String TASK_ID = "task-8241890";

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();

// Updating an existing DeliveryTask which is already CLOSED. Manually
// setting TaskOutcomeLocation with Driver SDK is not supported at this time.
UpdateDeliveryTaskRequest req = UpdateDeliveryTaskRequest.builder(TASK_ID)
    .setTaskOutcome(TaskOutcome.SUCCEEDED)
    .setTaskOutcomeTimestamp(now()) // Timestamp in milliseconds.
    .build();

try {
   DeliveryTask updatedTask = taskManager.updateTask(req);
   // Handle UpdateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle UpdateTaskRequest error.
}

車両を検索

車両は Driver SDK から検索できます。車両を検索する前に、Delivery Driver API を初期化してください。その後、次の例で車両を検索できます。

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleManager vehicleManager = api.getDeliveryVehicleManager();
try {
   DeliveryVehicle vehicle = vehicleManager.getVehicle().get();
   // Handle GetVehicleRequest DeliveryVehicle response.
} catch (Exception e)  {
   // Handle GetVehicleRequest error.
}

DeliveryVehicleManager は、Delivery Driver API の初期化中に提供された車両 ID のみを DeliveryVehicle で検索できます。