開始使用 Android 版 Driver SDK

基本系統需求

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

建構和依附元件設定

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

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 以上版本。詳情請參閱版本資訊

如要執行以驅動程式 SDK 建構的應用程式,Android 裝置必須安裝 Google Play 服務

設定開發專案

如要在 Google Cloud 控制台上設定開發專案,並取得專案的 API 金鑰,請按照下列步驟操作:

  1. 建立新的 Google Cloud 控制台專案,或選取現有專案,以便與驅動程式 SDK 搭配使用。請稍待幾分鐘,直到新專案顯示在 Google Cloud 控制台上。

  2. 如要執行試用版應用程式,專案必須具備 Maps SDK for Android 的存取權。在 Google Cloud 控制台中,選取「API 和服務」>「程式庫」,然後搜尋並啟用 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。請注意,最新版本的驅動程式 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 實作常見用途。

建立車輛

您可以透過驅動程式 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 未遵循有效的圖案。只有第一個 CarStop 可以位於任何 VehicleStopStates:NEW、ENROUTE 或 ARRIVED。目前停靠站後方的車輛停靠站必須位於新 VehicleStopState。

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

  • 車輛不存在。

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

車輛從停靠站出發及開始導航時,Fleet Engine 必須收到通知。您可以透過驅動程式 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,直到問題成功為止。

可能的問題包括:

  • 驅動程式 SDK 中未設定剩餘的 VehicleStops

車輛抵達停靠站

車輛抵達停靠站時,Fleet Engine 必須收到通知。您可以從驅動程式 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,直到問題成功為止。

可能的問題包括:

  • 驅動程式 SDK 中未設定剩餘的 VehicleStops

車輛完成一個停靠站

請務必在車輛完成停靠站時通知 Fleet Engine。導致所有與停靠站相關的工作都設為「已關閉」狀態。您可以從驅動程式 SDK 通知 Fleet Engine。

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

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

可能的問題包括:

  • 驅動程式 SDK 中未設定剩餘的 VehicleStops

關閉工作

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

如果工作尚未分配到需要關閉的車輛,請將工作更新為已關閉狀態。但無法重新開啟「已關閉」的工作。

關閉工作並不代表成功或失敗。這表示系統不再將該工作視為進行中。為追蹤運送狀態,請務必指出工作的實際結果,以便顯示運送結果。

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

或者,您也可以更新工作所指派車輛的工作順序,然後從停靠站清單中移除任務。

設定工作結果和結果位置

關閉工作並不表示成功或失敗。這表示系統不再將該工作視為進行中。針對運送追蹤產品,請務必指出工作的實際結果,以便系統顯示運送結果,並確保系統能夠為服務設定適當的帳單。工作結果一經設定即無法變更。不過,設定完成後,您還是可以修改工作結果時間和工作結果位置。

處於「已關閉」狀態的工作,可以將其結果設定為「SUCCEEDED」(成功) 或「FAILED」(失敗)。Fleet Engine 只會針對狀態為「SUCCEEDED」的提交工作收費。

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

以下範例說明如何使用驅動程式 SDK 設定工作結果和時間戳記。您無法使用驅動程式 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.
    }

查詢車輛

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