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

最小システム要件

モバイル デバイスに Android 6.0(API レベル 23)以降が搭載されている必要があります。

ビルドと依存関係の構成

Driver SDK バージョン 4.99 以降は Google Maven リポジトリで入手できます。

Gradle

次のコードを build.gradle ファイルに追加します。

repositories {
    ...
    google()
}

Maven

次のコードを pom.xml ファイルに追加します。

<project>
  ...
  <repositories>
    <repository>
      <id>google-maven-repository</id>
      <url>https://maven.google.com</url>
    </repository>
  </repositories>
  ...
</project>

プロジェクト構成

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

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

開発プロジェクトをセットアップする

Google Cloud コンソールで開発プロジェクトをセットアップし、プロジェクトの API キーを取得するには:

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

  2. デモアプリを実行するには、プロジェクトで Maps SDK for Android にアクセスできる必要があります。Google Cloud コンソールで [API とサービス] > [ライブラリ] を選択し、Maps SDK for Android を検索して有効にします。

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

Driver SDK をアプリに追加する

Driver SDK は Google Maven リポジトリから入手できます。リポジトリには、SDK のプロジェクト オブジェクト モデル(.pom)ファイルと Javadocs が含まれています。Driver SDK をアプリに追加するには:

  1. Gradle または Maven の構成に次の依存関係を追加します。選択したバージョンの Driver SDK の VERSION_NUMBER プレースホルダは置き換えます。

    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>
    
  2. Driver SDK は Navigation SDK に依存しています。この依存関係は、Navigation SDK の特定のバージョンが必要な場合は、次のようにビルド構成ファイルで明示的に定義する必要があります。上記のコードブロックを省略すると、プロジェクトは常にメジャー リリース バージョン内の Navigation SDK の最新バージョンをダウンロードできるようになります。Driver SDK と Navigation SDK の最新バージョンは、リリース前に組み合わせた動作について厳格なテストを受けています。

    それに応じて、開発環境とリリース環境の依存関係構成を調整します。

    Gradle

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

    dependencies {
      ...
      implementation 'com.google.android.libraries.navigation:navigation:5.0.0'
    }
    

    Maven

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

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.navigation</groupId>
        <artifactId>navigation</artifactId>
        <version>5.0.0</version>
      </dependency>
    </dependencies>
    

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

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

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

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

  1. ルートレベルの build.gradle ファイルを開き、buildscriptdependencies 要素に次のコードを追加します。

    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 を使用する場合は、アプリの法的通知セクションの一部としてアトリビューション テキストとオープンソース ライセンスを含める必要があります。帰属情報は、独立したメニュー項目として、または [About] メニュー項目の一部として含めることをおすすめします。

ライセンス情報は、アーカイブ解除された AAR ファイルの「third_party_licenses.txt」ファイルで確認できます。

オープンソースに関する通知を含める方法については、https://developers.google.com/android/guides/opensource をご覧ください。

依存関係

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

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

これらの依存関係がないと、Driver SDK が Fleet Engine サーバーと通信しようとしているときに、実行時にエラーが発生する可能性があります。

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

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

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

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 Web Token(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 の例外は、繰り返し発生しない限り、一時的なものとして扱われます。何度か試行すると、Driver SDK は永続的なエラーと見なし、更新の送信を停止します。

StatusListener によるステータスとエラーの報告

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 バージョン 23 以前)では、サーバーと通信するために SecurityProvider パッチが必要になる場合があります。Android での SSL の使用について詳しくは、Security GMS プロバイダをご覧ください。 この記事には、セキュリティ プロバイダにパッチを適用するためのコードサンプルも掲載されています。

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

*VehicleReporter インスタンスがあれば、位置情報の更新を簡単に有効にできます。

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

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

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

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

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

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

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

車両を作成する

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

車両を作成する前に、Delivery Driver API を初期化してください。車両 ID は、Driver SDK の初期化時に使用した車両 ID とプロバイダ 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 を再度呼び出します。

たとえば、次のような問題が考えられます。

  • 指定された VehicleStops は有効なパターンに従っていません。最初の VehicleStop のみを VehicleStopStates(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 状態に設定されます。Driver 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」状態に更新します。ただし、クローズしたタスクを再度開くことはできません。

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

Driver SDK を使用してタスクを閉じるには、タスクを車両に割り当てる必要があります。車両に割り当てられたタスクを閉じるには、タスクが行われる停車地を車両が完了したことを Fleet Engine に通知します。

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

タスクの結果と結果の場所を設定する

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

クローズ状態のタスクは、結果を [成功] または [失敗] に設定できます。Fleet Engine では、ステータスが [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 のみを検索できます。