最低系统要求
移动设备必须搭载 Android 5.0(API 级别 21)或更高版本。
前提条件
本指南假定您的应用已实现 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 环境变量。
与凭据关联的服务帐号电子邮件地址必须是工作区组的成员。
配置
配置 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 密钥,请执行以下操作:
创建一个新的 Google Cloud Console 项目,或者选择一个现有项目以用于 Driver SDK。等待几分钟,直到新项目在 Google Cloud Console 上显示。
若要运行演示版应用,您的项目必须有权访问 Maps SDK for Android。在 Google Cloud 控制台中,选择 API 和服务 > 库,然后搜索并启用 Maps SDK for Android。
选择 API 和服务 > 凭据 > 创建凭据 > API 密钥,获取项目的 API 密钥。如需详细了解如何获取 API 密钥,请参阅获取 API 密钥。
将 Driver SDK 添加到您的应用
Driver SDK 可通过私有 Maven 代码库获取。该代码库包含 SDK 的项目对象模型 (.pom) 文件和 Javadocs。如需将 Driver SDK 添加到您的应用,请执行以下操作:
按照“配置”部分中的说明,将您的环境设置为访问主机 Maven 代码库。
将以下依赖项添加到 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>
向您的应用添加 API 密钥
将 Driver SDK 添加到应用后,将 API 密钥添加到您的应用。您必须使用设置开发项目时获得的项目 API 密钥。
本部分介绍了如何存储 API 密钥,以便您的应用可以更安全地引用该密钥。您不应将 API 密钥签入版本控制系统。该文件应存储在 local.properties
文件中,该文件位于项目的根目录中。如需详细了解 local.properties
文件,请参阅 Gradle 属性文件。
如需简化此任务,请使用 Android 版 Secrets Gradle 插件。请按照以下步骤安装 Secrets Gradle 插件并安全地存储您的 API 密钥。
打开根级
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") } }
打开应用级
build.gradle
文件,并将以下代码添加到plugins
元素中。Groovy
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
Kotlin
id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
打开项目级目录中的
local.properties
,然后添加以下代码。请务必将YOUR_API_KEY
替换为您的 API 密钥。MAPS_API_KEY=YOUR_API_KEY
在
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,则必须在应用的法律声明部分添加提供方说明文本和开源许可。最好将归因作为独立的菜单项或关于菜单项的一部分包含在内。
您可以在驱动程序 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 来优化 build,则可能需要将以下行添加到 ProGuard 配置文件中:
-dontwarn com.google.**
-dontwarn io.grpc.**
-dontwarn okio.**
支持的最低 API 级别为 21。
初始化 SDK
必须提供提供方 ID(通常是 Google Cloud 项目 ID)才能初始化 DriverContext
对象。如需详细了解如何设置 Google Cloud 项目,请参阅身份验证和授权。
在使用 Driver SDK 之前,您必须先初始化 Navigation SDK。要初始化 SDK,请执行以下操作:
从
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; } } );
创建一个
DriverContext
对象,以填充必填字段。DriverContext driverContext = DriverContext.builder(application) .setProviderId(providerId) .setVehicleId(vehicleId) .setAuthTokenFactory(authTokenFactory) .setNavigator(navigator) .setRoadSnappedLocationProvider( NavigationApi.getRoadSnappedLocationProvider(application)) .build();
使用
DriverContext
对象初始化*DriverApi
。DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
从 API 对象获取
DeliveryVehicleReporter
。(DeliveryVehicleReporter
扩展了NavigationVehicleReporter
。)DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
使用 AuthTokenFactory
进行身份验证
Driver SDK 生成位置更新时,必须将这些更新发送到 Fleet Engine 服务器。为了对这些请求进行身份验证,驱动程序 SDK 将调用调用方提供的 AuthTokenFactory
实例。工厂负责在位置更新时生成身份验证令牌。
令牌的生成方式因开发者的具体情况而异。不过,实现可能需要执行以下操作:
- 从 HTTPS 服务器获取身份验证令牌(可能采用 JSON 格式)
- 解析和缓存令牌
- 过期后刷新令牌
如需详细了解 Fleet Engine 服务器预期的令牌,请参阅创建 JSON Web 令牌 (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
的状态和错误报告
由于 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。必须使用驱动程序 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 可以位于以下任何 VehicleStopState 中:NEW、ENROUTE 或 ARRIVED。当前停靠站后的 VehicleStops 必须处于新的 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.
}
可能会发生异常,阻止 Driver SDK 的内部状态更新。如果发生这种情况,请解决问题,然后再次调用 enrouteToNextStop
,直到成功为止。
潜在问题可能包括:
- 驱动程序 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.
}
可能会发生异常,阻止 Driver 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.
}
可能会发生异常,阻止 Driver SDK 的内部状态更新。如果发生这种情况,请解决问题,然后再次调用 completedStop
,直到成功为止。
潜在问题可能包括:
- 驱动程序 SDK 中未设置剩余的
VehicleStops
。
关闭任务
如需关闭已分配给车辆的任务,请通知 Fleet Engine 车辆已完成任务的停止点,或者从车辆停靠点列表中移除该任务。为此,您可以设置剩余车辆停止的列表,就像更新车辆的任务顺序一样。
如果任务尚未分配车辆且需要关闭,请将任务更新为“关闭”状态。但是,您无法重新打开已关闭的任务。
关闭任务并不代表成功或失败。它表示任务不再被视为正在进行。对于物流跟踪,必须指明任务的实际结果,以便显示交付结果。
必须向车辆分配任务,才能使用 Driver SDK 关闭任务。如需关闭已分配给车辆的任务,请通知 Fleet Engine 车辆已完成相应任务的停止点。
或者,您也可以更新任务被分配到的车辆的任务排序,然后从停靠点列表中移除所需的任务。
设置任务结果和结果位置
关闭任务并不代表成功或失败。它表示任务不再被视为正在进行。对于物流跟踪,必须指明任务的实际结果,以便显示交付结果,从而为服务提供适当的结算。任务设置后便无法更改。但是,您可以在设置任务结果时间和任务结果位置后对其进行修改。
处于“已关闭”状态的任务可以将其结果设置为“成功”或“失败”。Fleet Engine 仅对状态为“成功”的交付任务收费。
标记任务结果时,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
。