在 Android 设备上跟踪行程

请选择平台: Android iOS JavaScript

跟踪行程时,您的消费者应用会向消费者显示相应车辆的位置。为此,您的应用需要开始跟踪行程、更新行程进度,并在行程结束时停止跟踪行程。

本文档介绍了该流程的工作原理。

准备工作

确保您已设置以下各项:

  • 消费者应用的后端服务已就位,且您的服务已就绪 让消费者与车辆匹配。

  • 您已为应用设置地图

开始跟踪行程

当您的后端服务器将消费者与车辆进行匹配时, 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()
  }
}

更新行程进度

如需更新行程进度详情(例如车辆到达前需要行驶的距离和预计到达时间),您的应用需要注册和配置监听器,如以下示例所示。

  1. 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?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. 使用 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 的 Cloud 项目的 ID, 服务提供商
401 UNAUTHENTICATED 如果没有有效的身份验证凭据,您会收到此错误。 例如,在 JWT 令牌签名时不含行程 ID 或 JWT 令牌 已过期。
403 PERMISSION_DENIED 如果客户端权限不足,您会收到此错误 (例如,具有使用方角色的用户尝试调用 updateTrip),如果 JWT 令牌无效,或者客户端项目未启用该 API。 可能缺少 JWT 令牌,或者令牌已用行程 ID 签名, 与请求的行程 ID 不匹配。
429 RESOURCE_EXHAUSTED 资源配额为零或流量超出限制。
503 UNAVAILABLE 服务不可用。通常是服务器已关闭。
504 DEADLINE_EXCEEDED 超出请求时限。仅当调用方设置的时限比方法的默认时限短(即请求的时限不足以让服务器处理请求)并且请求未在时限范围内完成时,才会发生此错误。

处理使用方 SDK 错误

消费者 SDK 使用回调向消费者应用发送行程更新错误 机制。回调参数是平台特定的返回值类型 ( TripUpdateError 以及 NSError )。

提取状态代码

传递给回调函数的错误通常是 gRPC 错误,您也可以 从它们提取额外信息。对于 状态代码的完整列表,请参阅 状态代码及其在 gRPC 中的使用

Java

您可以提取提供错误详细信息的 gRPC 状态代码 (来自从 onTripUpdateError() 返回的 TripUpdateError)。

// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
  Status.Code code = error.getStatusCode();
}

Kotlin

您可以提取提供错误详细信息的 gRPC 状态代码 (从 onTripUpdateError() 返回的 TripUpdateError 中)。

// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
  val code = error.getStatusCode()
}

解读状态代码

状态代码涵盖两种错误:与服务器和网络相关的错误,以及 错误。

服务器和网络错误

以下状态代码针对的是网络错误或服务器错误, 无需采取任何措施来解决这些问题。使用方 SDK 会自动 能够从中恢复

状态代码说明
ABORTED 服务器已停止发送响应。这通常是由 服务器问题。
已取消 服务器终止了外发响应。这通常 发生以下情况:
当应用被发送到后台时,或者当
消费者应用。
INTERRUPTED
DEADLINE_EXCEEDED 服务器的响应时间过长。
UNAVAILABLE 服务器不可用。这通常是由网络所致 问题。

客户端错误

以下状态代码针对的是客户端错误,您必须采取措施 并加以解决。在您结束行程共享之前,Consumer SDK 会继续重试刷新行程,但在您采取行动之前,行程不会恢复。

状态代码说明
INVALID_ARGUMENT 消费者应用指定的行程名称无效;行程名称必须 遵循格式 providers/{provider_id}/trips/{trip_id}
NOT_FOUND 行程从未创建。
PERMISSION_DENIED 消费者应用权限不足。出现此错误的情况包括:
<ph type="x-smartling-placeholder">
    </ph>
  • 消费者应用没有权限
  • Google Cloud 中的项目未启用使用方 SDK 控制台。
  • JWT 令牌缺失或无效。
  • JWT 令牌的签名行程 ID 与 请求的行程。
RESOURCE_EXHAUSTED 资源配额为零,或者流量的速率超过 限速。
UNAUTHENTICATED 由于 JWT 令牌无效,请求未通过身份验证。如果 JWT 令牌在签名时未提供行程 ID,或者 JWT 令牌已过期,就会发生此错误。