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>

项目配置

如需使用驱动程序 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. 依次选择 API 和服务 > 凭据 > 创建凭据 > API 密钥,获取项目的 API 密钥。如需详细了解如何获取 API 密钥,请参阅获取 API 密钥

将驱动程序 SDK 添加到您的应用

驱动程序 SDK 可从 Google Maven 制品库获取。代码库包含 SDK 的项目对象模型 (.pom) 文件和 Javadocs。如需将驱动程序 SDK 添加到您的应用,请执行以下操作:

  1. 将以下依赖项添加到您的 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>
    
  2. Driver SDK 依赖于 Navigation SDK,此依赖项的配置方式如下:如果需要特定版本的 Navigation SDK,则需要在 build 配置文件中明确定义,如下所示。如果省略上述代码块,项目将始终在主要发布版本中下载最新版本的 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 密钥

将驱动程序 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>

在您的应用中添加必要的提供方说明

如果您在应用中使用驱动程序 SDK,则必须在应用的法律声明部分包含提供方说明文本和开源许可。最好以独立菜单项的形式提供提供方说明,或将提供方说明作为关于菜单项的一部分提供。

许可信息可以在未归档的 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 优化 build,则可能需要将以下行添加到 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。 (DeliveryVehicleReporter 扩展 NavigationVehicleReporter。)

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

正在通过 AuthTokenFactory 进行身份验证

当驱动程序 SDK 生成位置信息更新时,必须将这些更新发送到 Fleet Engine 服务器。为了对这些请求进行身份验证,驱动程序 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

由于驱动程序 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。必须使用 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。必须使用初始化驱动程序 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.
}

排定的经停点

您可以通过驱动程序 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.
    }

可能会发生异常,导致无法更新驱动程序 SDK 的内部状态。如果发生这种情况,请解决问题,然后再次调用 setVehicleStops,直到调用成功。

潜在问题可能包括:

  • 指定的 VehicleStop 未遵循有效的图案。只有第一个 VehicleStop 可处于以下任一 VehicleStopState:NEW、ENROUTE 或 ARRIVED。 当前停车点之后的 VehicleStop 必须处于新的 VehicleStopState。

  • 任务不存在或属于其他车辆。

  • 这辆车不存在。

车辆正在前往下一站

当车辆从停靠站离开以及开始导航时,Fleet Engine 必须收到通知。您可以通过驱动程序 SDK 通知舰队引擎。

在通知 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 车辆已完成 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,直到成功为止。

潜在问题可能包括:

  • 驱动程序 SDK 中未设置剩余的 VehicleStops

关闭任务

如需关闭已分配给车辆的任务,请通知 Fleet Engine 车辆已完成任务发生位置的停靠站,或将其从车辆停靠站列表中移除。为此,您可以设置其余车辆停靠站的列表,就像更新车辆的任务排序一样。

如果任务尚未分配车辆,并且需要关闭,请将任务更新为“已关闭”状态。不过,您无法重新打开“已关闭”任务。

关闭任务并不表示成功或失败。它表示任务不再被视为正在进行中。对于货运跟踪,请务必指明任务的实际结果,以便显示送货结果。

必须将任务分配给车辆,才能使用 Driver SDK 关闭任务。如需关闭已分配给车辆的任务,请通知 Fleet Engine 车辆已完成任务所在的停靠站。

或者,更新任务分配到的车辆的任务排序,然后从停靠点列表中移除任务。

设置任务结果和结果位置

关闭任务并不表示成功或失败。它表示任务不再被视为正在进行中。对于货运跟踪,请务必指明任务的实际结果,以显示交付结果,并确保服务进行适当的结算。设置后,您便无法更改任务结果。但是,您可以在设置任务结果时间和任务结果位置后进行修改。

处于“已关闭”状态的任务可将其结果设置为“成功”或“失败”。Fleet Engine 仅对状态为“成功”的传送任务收费,

标记任务结果时,Fleet Engine 会自动使用最近一次的已知车辆位置填充任务结果位置。您可以替换此行为。

以下示例展示了如何使用 Driver 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.
    }

查找车辆

您可以通过 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