開始使用 Android 版 Driver SDK

基本系統需求

行動裝置必須搭載 Android 6.0 (API 級別 23) 以上版本。

建構與依附元件設定

Google Maven 存放區提供驅動程式 SDK 4.99 以上版本。

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. 建立新的 Google Cloud Console 專案,或選取現有專案,以便與 Driver SDK 搭配使用。稍等幾分鐘,等待新專案顯示在 Google Cloud 控制台中。

  2. 如要執行試用版應用程式,專案必須具備 Maps SDK for Android 的存取權。在 Google Cloud 控制台中,依序選取「APIs & Services」(API 和服務) >「Library」(程式庫),然後搜尋並啟用 Maps SDK for Android。

  3. 依序選取「APIs & Services」(API 和服務) >「Credentials」(憑證) >「Create credentials」(建立憑證) >「API key」(API 金鑰),取得專案的 API 金鑰。如要進一步瞭解如何取得 API 金鑰,請參閱「取得 API 金鑰」一文。

將驅動程式 SDK 新增至應用程式

您可以從 Google Maven 存放區取得驅動程式 SDK。這個存放區包括 SDK 的專案物件模型 (.pom) 檔案和 Javadocs。如何在應用程式中新增 Driver SDK:

  1. 將以下依附元件新增至 Gradle 或 Maven 設定,取代所選驅動程式 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. 驅動程式 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 屬性檔案的說明

請使用 Secrets Gradle Plugin for Android 來簡化這項工作。請按照下列程序安裝 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,則必須在應用程式的法律聲明部分中加入作者資訊文字和開放原始碼授權。建議您將作者資訊以獨立選單項目的形式加入,或納入「About」選單項目中。

您可以在未封存的 AAR 檔案中的「third_party_licenses.txt」檔案找到授權資訊。

請參閱 https://developers.google.com/android/guides/opensource,瞭解如何加入開放原始碼通知。

依附元件

驅動程式 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 級別為 23。

初始化 SDK

必須提供提供者 ID (通常為 Google Cloud 專案 ID),才能初始化 DriverContext 物件。如要進一步瞭解如何設定 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。(DeliveryVehicleReporter 擴充 NavigationVehicleReporter。)

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

透過 AuthTokenFactory 進行驗證

當驅動程式 SDK 產生位置更新通知時,必須將這些更新內容傳送至 Fleet Engine 伺服器。為驗證這些要求,驅動程式 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 重複發生,否則系統會將例外狀況視為暫時性的例外狀況。經過多次嘗試後,驅動程式 SDK 會假設錯誤是永久性,並停止嘗試傳送更新。

包含 StatusListener 的狀態和 Error Reporting

由於驅動程式 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 注意事項

在內部,驅動程式 SDK 實作會使用 SSL/TLS,安全地與 Fleet Engine 伺服器通訊。較舊的 Android (API 版本 23 以下) 可能需要 SecurityProvider 修補程式才能與伺服器通訊。如要進一步瞭解如何在 Android 中使用 SSL,請參閱「安全性 GMS 供應商」。本文也提供了修補安全性提供者的程式碼範例。

啟用位置更新通知

建立 *VehicleReporter 執行個體後,就可以直接啟用位置更新功能:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

系統會盡可能定期傳送位置更新資訊。每次位置更新也代表車輛已連上網路。

根據預設,報表間隔為 10 秒。您可以使用 reporter.setLocationReportingInterval(long, TimeUnit) 變更報表間隔。支援的更新間隔時間下限為 5 秒。頻繁更新可能會導致要求變慢,並造成錯誤。

停用位置更新通知

駕駛人輪班後,您可以呼叫 DeliveryVehicleReporter.disableLocationTracking 來停止位置更新通知。

信任的模型用途

本節說明如何在使用信任的模型時,使用驅動程式 SDK 實作常見用途。

製作車輛

您可以透過 Driver SDK 建立車輛,

建立車輛前,請務必初始化 Delivery Driver API。建立車輛 ID 時,必須使用在驅動程式 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。您必須使用驅動程式 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.
}

預定停用

您可以透過驅動程式 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.
    }

更新工作排序

您可以透過驅動程式 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.
    }

可能導致無法更新驅動程式 SDK 內部狀態的例外狀況。如果發生這種情況,請解決問題,然後再次呼叫 setVehicleStops,直到呼叫成功為止。

潛在問題包括:

  • 指定的 VehicleStops 未採用有效的模式。只有第一輛車停靠站可屬於任何 VehicleStopStates:NEW、ENROUTE 或 ARRIVED。目前停靠站之後的車輛停靠站必須位於新車停靠站狀態中。

  • 工作不存在或屬於其他車輛。

  • 這輛車不存在。

車輛正在前往下一個停靠站

當車輛從停靠站出發及開始導航時,必須通知機群引擎。您可以透過 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.
    }

例外狀況可能會導致無法更新驅動程式 SDK 的內部狀態。如果發生這種情況,請解決問題,然後再次呼叫 enrouteToNextStop,直到成功為止。

潛在問題包括:

  • Driver SDK 中沒有任何剩餘的 VehicleStops

車輛抵達停靠站

車輛抵達停靠站時,機群引擎必須收到通知。您可以從驅動程式 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.
}

例外狀況可能會使驅動程式 SDK 的內部狀態無法更新。如果發生這種情況,請解決問題,然後再次呼叫 arrivedAtStop,直到成功為止。

潛在問題包括:

  • Driver SDK 中沒有任何剩餘的 VehicleStops

車輛完成停靠站

車輛抵達停靠站時,您必須通知 Fleet Engine。這則通知會讓所有與停靠站相關聯的工作都設為「已關閉」狀態。您可以從驅動程式 SDK 通知 Fleet Engine。

通知 Fleet Engine 車輛已完成車輛 VehicleStop,如以下範例所示。

    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.
    }

例外狀況可能會使驅動程式 SDK 的內部狀態無法更新。如果發生這種情況,請解決問題,然後再次呼叫 completedStop,直到成功為止。

潛在問題包括:

  • Driver SDK 中沒有任何剩餘的 VehicleStops

關閉工作

如要關閉已指派給車輛的工作,請通知 Fleet Engine 指出車輛已完成工作停靠站,或將其從車輛停靠站清單中移除。如要這麼做,您可以設定其餘車輛停靠站清單,就像更新車輛工作順序時一樣。

如果工作尚未指派車輛且需要關閉,請將任務更新為關閉狀態。但無法重新開啟已關閉的工作。

關閉工作不代表工作成功或失敗。這表示工作已不再考慮到進行中。至於運送追蹤,請務必指出工作的實際結果,以便顯示送達結果。

必須將工作指派給車輛,才能使用驅動程式 SDK 關閉工作。如要關閉已指派給車輛的工作,請通知 Fleet Engine,說明車輛已完成工作的停靠站。

或者,您也可以針對指派給工作的車輛更新工作順序,然後從停止清單移除任務。

設定工作結果和結果位置

關閉工作不代表工作成功或失敗。這表示工作已不再考慮到進行中。至於運送追蹤,請務必指出工作的實際結果,以便系統顯示送達結果,以便正確計費服務。設定後即無法變更工作結果。不過,您可以先設定工作結果時間和工作結果位置,再加以修改。

處於「已關閉」狀態的工作,可以將結果設為「成功」或「失敗」。Fleet Engine 只會針對狀態為 SUCCEEDED 的傳送工作收費。

標記工作結果時,Fleet Engine 會自動將工作結果位置填入最後已知的車輛位置。您可以覆寫這個行為。

以下範例說明如何使用驅動程式 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 只能查詢 DeliveryVehicle,找出 Delivery Driver API 初始化期間提供的車輛 ID。