当您跟踪行程时,您的消费者应用会向消费者显示相应车辆的位置。为此,应用需要开始跟踪行程、更新行程进度,并在行程完成时停止跟踪。
本文档介绍了该流程的运作方式。
准备工作
请确保您已设置以下内容:
- 面向消费者的应用的后端服务已就绪,用于将消费者与车辆进行匹配的服务已正常运行。 
- 您已为应用设置地图。 
开始关注行程
当后端服务器将消费者与车辆匹配时,请使用 JourneySharingSession 开始跟踪行程。
以下示例代码演示了如何在视图加载后开始跟踪行程。
Java
public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {
  // Class implementation
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Create a TripModel instance to listen for updates to the trip specified by this trip name.
    String tripName = ...;
    TripModelManager tripModelManager = consumerApi.getTripModelManager();
    TripModel tripModel = tripModelManager.getTripModel(tripName);
    // Create a JourneySharingSession instance based on the TripModel.
    JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session);
    // Register for trip update events.
    tripModel.registerTripCallback(new TripModelCallback() {
      @Override
      public void onTripETAToNextWaypointUpdated(
          TripInfo tripInfo, @Nullable Long timestampMillis) {
        // ...
      }
      @Override
      public void onTripActiveRouteRemainingDistanceUpdated(
          TripInfo tripInfo, @Nullable Integer distanceMeters) {
        // ...
      }
      // ...
    });
  }
  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}
Kotlin
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
  // Class implementation
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Create a TripModel instance to listen for updates to the trip specified by this trip name.
    val tripName = "tripName"
    val tripModelManager = consumerApi.getTripModelManager()
    val tripModel = tripModelManager.getTripModel(tripName)
    // Create a JourneySharingSession instance based on the TripModel.
    val session = JourneySharingSession.createInstance(tripModel)
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session)
    // Register for trip update events.
    tripModel.registerTripCallback(
      object : TripModelCallback() {
        override fun onTripETAToNextWaypointUpdated(
          tripInfo: TripInfo,
          timestampMillis: Long?,
        ) {
          // ...
        }
        override fun onTripActiveRouteRemainingDistanceUpdated(
          tripInfo: TripInfo,
          distanceMeters: Int?,
        ) {
          // ...
        }
      // ...
    })
  }
  override fun onDestroy() {
    super.onDestroy()
    journeySharingSession?.stop()
  }
}
更新行程进度
如需更新行程进度详情(例如车辆到达目的地之前需要行驶的距离和预计到达时间),您的应用需要注册并配置监听器,如以下示例所示。
- 在 - TripModel对象上注册监听器。- Java- // Create a TripModel instance for listening to updates to the trip specified by this trip name. String tripName = ...; TripModelManager tripModelManager = consumerApi.getTripModelManager(); TripModel tripModel = tripModelManager.getTripModel(tripName); // Create a JourneySharingSession instance based on the TripModel. JourneySharingSession session = JourneySharingSession.createInstance(tripModel); // Add the JourneySharingSession instance on the map for updating the UI. consumerController.showSession(session); // Register for trip update events. tripModel.registerTripCallback(new TripModelCallback() { @Override public void onTripETAToNextWaypointUpdated( TripInfo tripInfo, @Nullable Long timestampMillis) { // ... } @Override public void onTripActiveRouteRemainingDistanceUpdated( TripInfo tripInfo, @Nullable Integer distanceMeters) { // ... } // ... });- Kotlin- // Create a TripModel instance for listening to updates to the trip specified by this trip name. val tripName = "tripName" val tripModelManager = consumerApi.getTripModelManager() val tripModel = tripModelManager.getTripModel(tripName) // Create a JourneySharingSession instance based on the TripModel. val session = JourneySharingSession.createInstance(tripModel) // Add the JourneySharingSession instance on the map for updating the UI. consumerController.showSession(session) // Register for trip update events. tripModel.registerTripCallback( object : TripModelCallback() { override fun onTripETAToNextWaypointUpdated( tripInfo: TripInfo, timestampMillis: Long?, ) { // ... } override fun onTripActiveRouteRemainingDistanceUpdated( tripInfo: TripInfo, distanceMeters: Int?, ) { // ... } // ... })
- 使用 - TripModelOptions为行程配置监听器。- Java- // Set refresh interval to 2 seconds. TripModelOptions tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build(); tripModel.setTripModelOptions(tripOptions);- Kotlin- // Set refresh interval to 2 seconds. val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build() tripModel.setTripModelOptions(tripOptions)
停止关注行程
确保您的应用在不再需要时停止跟踪行程,例如当司机在后端将行程标记为“完成”时。停止行程分享可避免向 Fleet Engine 发送不必要的网络请求,并防止出现内存泄漏。
使用 JourneySharingSession 停止跟踪行程,如以下示例代码所示。
Java
public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {
  // Class implementation
  @Override
  protected void onDestroy() {
    super.onDestroy();
    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}
Kotlin
class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {
  // Class implementation
  override fun onDestroy() {
    super.onDestroy()
    journeySharingSession?.stop()
  }
}
处理行程错误
onTripRefreshError 方法会显示在行程监控期间发生的错误。错误消息遵循 Google Cloud 错误标准。如需详细了解错误消息定义和所有错误代码,请参阅 Google Cloud 错误文档。
以下是行程监控期间可能会发生的一些常见错误:
| HTTP | RPC | 说明 | 
|---|---|---|
| 400 | INVALID_ARGUMENT | 客户端指定了无效的行程名称。行程名称必须采用 providers/{provider_id}/trips/{trip_id}格式。provider_id 必须是服务提供商所拥有的 Cloud 项目的 ID。 | 
| 401 | UNAUTHENTICATED | 如果没有有效的身份验证凭据,您会收到此错误。 例如,如果 JWT 令牌在签名时未包含行程 ID,或者 JWT 令牌已过期。 | 
| 403 | PERMISSION_DENIED | 如果客户端没有足够的权限(例如,具有消费者角色的用户尝试调用 updateTrip)、JWT 令牌无效或未为客户端项目启用 API,您会收到此错误。 JWT 令牌可能缺失,或者令牌的签名所用的行程 ID 与所请求的行程 ID 不匹配。 | 
| 429 | RESOURCE_EXHAUSTED | 资源配额为零或流量速率超出限制。 | 
| 503 | UNAVAILABLE | 服务不可用。通常是服务器已关闭。 | 
| 504 | DEADLINE_EXCEEDED | 超出请求时限。仅当调用者设置的时限比方法的默认时限短(即请求的时限不足以让服务器处理请求)并且请求未在时限范围内完成时,才会发生此错误。 | 
处理 Consumer SDK 错误
Consumer SDK 使用回调机制将行程更新错误发送到使用方应用。回调参数是平台专用的返回类型(Android 上为 TripUpdateError,iOS 上为 NSError)。
提取状态代码
传递给回调的错误通常是 gRPC 错误,您还可以从中提取状态代码形式的其他信息。如需查看状态代码的完整列表,请参阅 gRPC 中的状态代码及其用途。
Java
您可以从 onTripUpdateError() 返回的 TripUpdateError 中提取 gRPC 状态代码,该代码可提供有关错误的详细信息。
// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
  Status.Code code = error.getStatusCode();
}
Kotlin
您可以从 onTripUpdateError() 返回的 TripUpdateError 中提取 gRPC 状态代码,该代码可提供有关错误的详细信息。
// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
  val code = error.getStatusCode()
}
解读状态代码
状态代码涵盖两种类型的错误:服务器和网络相关错误,以及客户端错误。
服务器和网络错误
以下状态代码表示网络或服务器错误,您无需采取任何措施来解决这些错误。Consumer SDK 会自动从中恢复。
| 状态代码 | 说明 | 
|---|---|
| ABORTED | 服务器停止发送响应。这通常是由服务器问题引起的。 | 
| 已取消 | 服务器终止了传出响应。通常,当 应用被发送到后台时,或者当 消费者应用中发生状态变化时,就会发生这种情况。 | 
| INTERRUPTED | |
| DEADLINE_EXCEEDED | 服务器响应时间过长。 | 
| UNAVAILABLE | 服务器不可用。这通常是由网络问题引起的。 | 
客户端错误
以下状态代码表示客户端错误,您必须采取措施来解决这些错误。在您结束行程分享之前,Consumer SDK 会继续尝试刷新行程,但除非您采取行动,否则它不会恢复。
| 状态代码 | 说明 | 
|---|---|
| INVALID_ARGUMENT | 消费者应用指定的行程名称无效;行程名称必须遵循 providers/{provider_id}/trips/{trip_id}格式。 | 
| NOT_FOUND | 行程从未创建。 | 
| PERMISSION_DENIED | 消费者应用权限不足。在以下情况下,会发生此错误: 
 | 
| RESOURCE_EXHAUSTED | 资源配额为零,或者流量流速超过了速度限制。 | 
| UNAUTHENTICATED | 由于 JWT 令牌无效,请求未通过身份验证。如果 JWT 令牌在签名时未包含行程 ID,或者 JWT 令牌已过期,就会发生此错误。 |