背靠背行程是指一项接连发生的排他性独立行程,驾驶员承诺在完成当前行程之前接下一个消费者的行程。
背靠背行程与单目的地行程之间的主要区别在于,对于连续行程,行程运营者可以将行程分配给已分配行程的车辆。
本教程将引导您完成创建背靠背行程的过程。还展示了如何将该行程与您的消费者应用集成,以便您的客户可以通过他们的手机直观地查看行程进度。您可以使用 Consumer SDK 进行此集成。
前提条件
如需完成本教程,请务必完成以下操作:
设置 Fleet Engine。如需了解详情,请参阅 Fleet Engine:初始设置。
将您的应用与驱动程序 SDK 集成。如需了解详情,请参阅适用于 Android 的初始化驱动程序 SDK 和适用于 iOS 的驱动程序 SDK 集成指南。
将面向消费者的应用与消费者 SDK 集成。如需了解详情,请参阅适用于 Android 的消费者 SDK 使用入门和适用于 iOS 的消费者 SDK 使用入门。
设置授权令牌。如需详细了解授权令牌,请参阅 Fleet Engine 使用入门指南中的创建 JSON Web 令牌以进行授权,以及 Fleet Engine 消费者 SDK 文档中的身份验证和授权。
第 1 步:在 Fleet Engine 中创建车辆
车辆是代表车队中车辆的对象。您必须在 Fleet Engine 中创建这些集群,才能在消费者应用中跟踪它们。
您可以使用以下两种方法之一创建车辆:
- gRPC
- 使用
CreateVehicleRequest
请求消息调用CreateVehicle()
方法。您必须拥有 Fleet Engine 超级用户权限才能调用CreateVehicle()
。 - REST
- 调用
https://fleetengine.googleapis.com/v1/providers.vehicles.create
。
注意事项
制作车辆时需注意以下事项。
请务必将初始车辆状态设置为
OFFLINE
。这样可确保 Fleet Engine 能够发现您的车辆,以便进行行程匹配。车辆的
provider_id
必须与 Google Cloud 项目(其中包含用于调用 Fleet Engine 的服务帐号)的项目 ID 相同。虽然多个服务帐号可以访问同一拼车提供商的 Fleet Engine,但 Fleet Engine 目前不支持来自访问同一车辆的不同 Google Cloud 项目的服务帐号。从
CreateVehicle()
返回的响应包含Vehicle
实例。如果您尚未使用UpdateVehicle()
更新实例,则七天后将将其删除。您应在调用CreateVehicle()
之前调用GetVehicle()
,只是为了确认车辆尚不存在。如果GetVehicle()
返回NOT_FOUND
错误,则应继续调用CreateVehicle()
。如需了解详情,请参阅车辆及其生命周期。
示例
以下提供程序代码示例演示了如何在 Fleet Engine 中创建车辆。
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);
String parent = "providers/" + PROJECT_ID;
Vehicle vehicle = Vehicle.newBuilder()
.setVehicleState(VehicleState.OFFLINE) // Initial state
.addSupportedTripTypes(TripType.EXCLUSIVE)
.setMaximumCapacity(4)
.setVehicleType(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
.build();
CreateVehicleRequest createVehicleRequest = CreateVehicleRequest.newBuilder()
.setParent(parent)
.setVehicleId("8241890") // Vehicle ID assigned by solution provider.
.setVehicle(vehicle) // Initial state.
.build();
// The Vehicle is created in the OFFLINE state, and no initial position is
// provided. When the driver app calls the rideshare provider, the state can be
// set to ONLINE, and the driver app updates the vehicle location.
try {
Vehicle createdVehicle = vehicleService.createVehicle(createVehicleRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case ALREADY_EXISTS:
break;
case PERMISSION_DENIED:
break;
}
return;
}
如需创建支持“背靠背”行程的 Vehicle
,您必须在传递给 CreateVehicleRequest
的 Vehicle
对象中将 backToBackEnabled
字段设置为 true
。
Vehicle vehicle = Vehicle.newBuilder()
.setVehicleState(VehicleState.OFFLINE)
.addSupportedTripTypes(TripType.EXCLUSIVE)
.setMaximumCapacity(4)
.setVehicleType(VehicleType.newBuilder().setCategory(VehicleType.Category.AUTO))
.setBackToBackEnabled(true) // Set as 'true' so vehicle can be assigned back-to-back trips.
.build();
第 2 步:启用位置跟踪
位置跟踪是指在行程中跟踪车辆的位置,驾驶员应用会向 Fleet Engine 发送遥测数据,其中包含车辆的当前位置。这种不断更新的位置信息流用于传达车辆沿行程路线的进度。启用位置跟踪后,驾驶员应用开始以默认频率(每 5 秒一次)发送此遥测数据。
您可以按以下步骤为 Android 和 iOS 启用位置跟踪:
调用 Android 驱动程序 SDK 方法
enableLocationTracking()
。将 iOS 版驱动程序 SDK 的布尔值属性
locationTrackingEnabled
设置为true
。
示例
以下代码示例演示了如何启用位置跟踪。
Java
RidesharingVehicleReporter vehicleReporter = ...;
vehicleReporter.enableLocationTracking();
Kotlin
val vehicleReporter = ...
vehicleReporter.enableLocationTracking()
Swift
vehicleReporter.locationTrackingEnabled = true
Objective-C
_vehicleReporter.locationTrackingEnabled = YES;
第 3 步:将车辆的状态设为在线
您可以通过将车辆的状态设置为 online 来使车辆投入服务(即使其可供使用),但您必须先启用位置信息跟踪,然后才能执行此操作。
对于 Android 和 iOS,您可以将车辆的状态设置为在线,如下所示:
调用 Android 驱动程序 SDK 方法
setVehicleState(VehicleState.ONLINE)
。调用 Driver SDK for iOS 方法
vehicleReporter.update(.online)
。
示例
以下代码示例演示了如何将车辆的状态设置为 ONLINE
。
Java
vehicleReporter.setVehicleState(VehicleState.ONLINE);
Kotlin
vehicleReporter.setVehicleState(VehicleState.ONLINE)
Swift
vehicleReporter.update(.online)
Objective-C
[_vehicleReporter updateVehicleState:GMTDVehicleStateOnline];
第 4 步:在 Fleet Engine 中创建行程
如需创建背靠背的行程,您可以创建一个 Trip
对象,就像创建单目的地行程一样。
行程是一个表示行程的对象,它是一个地理坐标点集合,包括出发地、航点和下车点。您必须为每个行程请求创建一个 Trip
对象,以便将请求与车辆匹配,然后进行跟踪。
- 使用
CreateTripRequest
请求消息调用CreateTrip()
方法,以创建行程。
提供必需属性
若要创建背靠背行程,您必须提供以下字段:
parent
- 一个包含提供方 ID 的字符串。此值必须与用于调用 Fleet Engine 的服务账号所属 Google Cloud 项目的项目 ID 相同
trip_id
- 您创建的字符串,用于唯一标识此行程。
trip
- 要创建的
Trip
对象。
必须在传递给 CreateTripRequest
的 Trip
对象中设置以下字段:
trip_type
TripType.EXCLUSIVE
pickup_point
- 行程的出发地。
dropoff_point
- 行程的下车点。创建行程时,此字段不是必填字段,稍后可通过调用
UpdateTrip
进行设置。
示例
以下后端集成示例演示了如何创建行程并将其分配给车辆。
// A vehicle with ID 'my-vehicle' is already created and it is assigned to a trip with ID 'current-trip'.
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String VEHICLE_ID =" my-vehicle";
static final String TRIP_ID = "back-to-back-trip");
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
String parent = "providers/" + PROJECT_ID;
Trip trip = Trip.newBuilder()
.setTripType(TripType.EXCLUSIVE)
.setPickupPoint(
TerminalLocation.newBuilder().setPoint(
LatLng.newBuilder()
.setLatitude(-6.195139).setLongitude(106.820826)))
.setDropoffPoint(
TerminalLocation.newBuilder().setPoint(
LatLng.newBuilder()
.setLatitude(-6.1275).setLongitude(106.6537)))
.setVehicleId(VEHICLE_ID)
.build();
// Create trip request
CreateTripRequest createTripRequest = CreateTripRequest.newBuilder()
.setParent(parent)
.setTripId(TRIP_ID)
.setTrip(trip)
.build();
// Error handling.
try {
// Fleet Engine automatically assigns a 'waypoints' list to the trip containing
// the vehicle's current trip waypoints.
Trip createdTrip =
tripService.createTrip(createTripRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case ALREADY_EXISTS:
break;
case PERMISSION_DENIED:
break;
}
return;
}
第 5 步:使用车辆 ID 和航点更新行程
您必须使用车辆 ID 配置行程,以便 Fleet Engine 可以沿路线跟踪车辆。对于背靠背模式,即使已向车辆分配行程,也仍会将行程分配给相应车辆。
- 您可以通过使用
UpdateTripRequest
调用UpdateTrip
端点,使用车辆 ID 更新行程。使用update_mask
字段指定您要更新车辆 ID。
将行程分配给车辆后,Fleet Engine 会自动将与连续行程关联的航点添加到车辆的航点字段。行程的 remainingWaypoints
字段包含将在行程中途下车之前访问的所有航点的列表,包括并发行程中的航点。
例如,假设有两个连续的行程:行程 A 和行程 B。车辆已接走行程 A 的消费者,在前往下车点的途中,司机会收到为下一行程(行程 B)接其他消费者的请求。
- 调用
getVehicle()
会返回剩余航点 (remainingWaypoints
) 的列表,其中包含
下车点 → B 上车 → B 下车。 getTrip()
或行程 A 的onTripRemainingWaypointsUpdated
回调会返回包含“离开”事件的剩余航点 (remainingWaypoints
) 列表。getTrip()
或行程 B 的onTripRemainingWaypointsUpdated
回调会返回其余航点 (remainingWaypoints
) 的列表,其中包含 A Drop-off → B Pickup → B Drop-off。
第 6 步:在消费者应用中监听行程更新
对于 Android,您可以通过从
TripModelManager
获取TripModel
对象并注册TripModelCallback
监听器,来监听行程的数据更新。对于 iOS,您可以通过从
GMTCTripService
获取GMTCTripModel
对象并注册GMTCTripModelSubscriber
订阅者来监听行程的数据更新。
借助 TripModelCallback
监听器和 GMTCTripModelSubscriber
订阅者,您的应用可在每次刷新时根据自动刷新间隔接收定期行程进度更新。只有发生变化的值才能触发回调。否则,回调将保持静默状态。
无论数据发生怎样的变化,系统始终会调用 TripModelCallback.onTripUpdated()
和 tripModel(_:didUpdate:updatedPropertyFields:)
方法。
示例 1
以下代码示例演示了如何从 TripModelManager
/GMTCTripService
获取 TripModel
并在其上设置监听器。
Java
// Start journey sharing after a trip has been created via Fleet Engine.
TripModelManager tripModelManager = consumerApi.getTripModelManager();
// Get a TripModel object.
TripModel tripModel = tripModelManager.getTripModel(tripName);
// Register a listener on the trip.
TripModelCallback tripCallback = new TripModelCallback() {
...
};
tripModel.registerTripCallback(tripCallback);
// Set the refresh interval.
TripModelOptions tripModelOptions = TripModelOptions.builder()
.setRefreshInterval(5000) // interval in milliseconds, so 5 seconds
.build();
tripModel.setTripModelOptions(tripModelOptions);
// The trip stops auto-refreshing when all listeners are unregistered.
tripModel.unregisterTripCallback(tripCallback);
Kotlin
// Start journey sharing after a trip has been created via Fleet Engine.
val tripModelManager = consumerApi.getTripModelManager()
// Get a TripModel object.
val tripModel = tripModelManager.getTripModel(tripName)
// Register a listener on the trip.
val tripCallback = TripModelCallback() {
...
}
tripModel.registerTripCallback(tripCallback)
// Set the refresh interval.
val tripModelOptions =
TripModelOptions.builder()
.setRefreshInterval(5000) // interval in milliseconds, so 5 seconds
.build()
tripModel.setTripModelOptions(tripModelOptions)
// The trip stops auto-refreshing when all listeners are unregistered.
tripModel.unregisterTripCallback(tripCallback)
Swift
let tripService = GMTCServices.shared().tripService
// Create a tripModel instance for listening for updates from the trip
// specified by the trip name.
let tripModel = tripService.tripModel(forTripName: tripName)
// Register for the trip update events.
tripModel.register(self)
// Set the refresh interval (in seconds).
tripModel.options.autoRefreshTimeInterval = 5
// Unregister for the trip update events.
tripModel.unregisterSubscriber(self)
Objective-C
GMTCTripService *tripService = [GMTCServices sharedServices].tripService;
// Create a tripModel instance for listening for updates from the trip
// specified by the trip name.
GMTCTripModel *tripModel = [tripService tripModelForTripName:tripName];
// Register for the trip update events.
[tripModel registerSubscriber:self];
// Set the refresh interval (in seconds).
tripModel.options.autoRefreshTimeInterval = 5;
// Unregister for the trip update events.
[tripModel unregisterSubscriber:self];
示例 2
以下代码示例演示了如何设置 TripModelCallback
监听器和 GMTCTripModelSubscriber
订阅者。
Java
// Implements a callback for the trip model so your app can listen for trip
// updates from Fleet Engine.
TripModelCallback subscriber =
new TripModelCallback() {
@Override
public void onTripStatusUpdated(TripInfo tripInfo, @TripStatus int status) {
// ...
}
@Override
public void onTripActiveRouteUpdated(TripInfo tripInfo, List<LatLng> route) {
// ...
}
@Override
public void onTripVehicleLocationUpdated(
TripInfo tripInfo, @Nullable VehicleLocation vehicleLocation) {
// ...
}
@Override
public void onTripPickupLocationUpdated(
TripInfo tripInfo, @Nullable TerminalLocation pickup) {
// ...
}
@Override
public void onTripPickupTimeUpdated(TripInfo tripInfo, @Nullable Long timestampMillis) {
// ...
}
@Override
public void onTripDropoffLocationUpdated(
TripInfo tripInfo, @Nullable TerminalLocation dropoff) {
// ...
}
@Override
public void onTripDropoffTimeUpdated(TripInfo tripInfo, @Nullable Long timestampMillis) {
// ...
}
@Override
public void onTripETAToNextWaypointUpdated(
TripInfo tripInfo, @Nullable Long timestampMillis) {
// ...
}
@Override
public void onTripActiveRouteRemainingDistanceUpdated(
TripInfo tripInfo, @Nullable Integer distanceMeters) {
// ...
}
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
// ...
}
@Override
public void onTripUpdated(TripInfo tripInfo) {
// ...
}
@Override
public void onTripRemainingWaypointsUpdated(
TripInfo tripInfo, List<TripWaypoint> waypointList) {
// ...
}
@Override
public void onTripIntermediateDestinationsUpdated(
TripInfo tripInfo, List<TerminalLocation> intermediateDestinations) {
// ...
}
@Override
public void onTripRemainingRouteDistanceUpdated(
TripInfo tripInfo, @Nullable Integer distanceMeters) {
// ...
}
@Override
public void onTripRemainingRouteUpdated(TripInfo tripInfo, List<LatLng> route) {
// ...
}
};
Kotlin
// Implements a callback for the trip model so your app can listen for trip
// updates from Fleet Engine.
val subscriber =
object : TripModelCallback() {
override fun onTripStatusUpdated(tripInfo: TripInfo, status: @TripStatus Int) {
// ...
}
override fun onTripActiveRouteUpdated(tripInfo: TripInfo, route: List<LatLng>) {
// ...
}
override fun onTripVehicleLocationUpdated(
tripInfo: TripInfo,
vehicleLocation: VehicleLocation?
) {
// ...
}
override fun onTripPickupLocationUpdated(tripInfo: TripInfo, pickup: TerminalLocation?) {
// ...
}
override fun onTripPickupTimeUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
// ...
}
override fun onTripDropoffLocationUpdated(tripInfo: TripInfo, dropoff: TerminalLocation?) {
// ...
}
override fun onTripDropoffTimeUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
// ...
}
override fun onTripETAToNextWaypointUpdated(tripInfo: TripInfo, timestampMillis: Long?) {
// ...
}
override fun onTripActiveRouteRemainingDistanceUpdated(
tripInfo: TripInfo,
distanceMeters: Int?
) {
// ...
}
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
// ...
}
override fun onTripUpdated(tripInfo: TripInfo) {
// ...
}
override fun onTripRemainingWaypointsUpdated(
tripInfo: TripInfo,
waypointList: List<TripWaypoint>
) {
// ...
}
override fun onTripIntermediateDestinationsUpdated(
tripInfo: TripInfo,
intermediateDestinations: List<TerminalLocation>
) {
// ...
}
override fun onTripRemainingRouteDistanceUpdated(tripInfo: TripInfo, distanceMeters: Int?) {
// ...
}
override fun onTripRemainingRouteUpdated(tripInfo: TripInfo, route: List<LatLng>) {
// ...
}
}
Swift
class TripModelSubscriber: NSObject, GMTCTripModelSubscriber {
func tripModel(_: GMTCTripModel, didUpdate trip: GMTSTrip?, updatedPropertyFields: GMTSTripPropertyFields) {
// Update the UI with the new `trip` data.
updateUI(with: trip)
...
}
func tripModel(_: GMTCTripModel, didUpdate tripStatus: GMTSTripStatus) {
// Handle trip status did change.
}
func tripModel(_: GMTCTripModel, didUpdateActiveRoute activeRoute: [GMTSLatLng]?) {
// Handle trip active route did update.
}
func tripModel(_: GMTCTripModel, didUpdate vehicleLocation: GMTSVehicleLocation?) {
// Handle vehicle location did update.
}
func tripModel(_: GMTCTripModel, didUpdatePickupLocation pickupLocation: GMTSTerminalLocation?) {
// Handle pickup location did update.
}
func tripModel(_: GMTCTripModel, didUpdateDropoffLocation dropoffLocation: GMTSTerminalLocation?) {
// Handle drop off location did update.
}
func tripModel(_: GMTCTripModel, didUpdatePickupETA pickupETA: TimeInterval) {
// Handle the pickup ETA did update.
}
func tripModel(_: GMTCTripModel, didUpdateDropoffETA dropoffETA: TimeInterval) {
// Handle the drop off ETA did update.
}
func tripModel(_: GMTCTripModel, didUpdateRemaining remainingWaypoints: [GMTSTripWaypoint]?) {
// Handle updates to the pickup, dropoff or intermediate destinations of the trip.
}
func tripModel(_: GMTCTripModel, didFailUpdateTripWithError error: Error?) {
// Handle the error.
}
func tripModel(_: GMTCTripModel, didUpdateIntermediateDestinations intermediateDestinations: [GMTSTerminalLocation]?) {
// Handle the intermediate destinations being updated.
}
...
}
Objective-C
@interface TripModelSubscriber : NSObject <GMTCTripModelSubscriber>
@end
@implementation TripModelSubscriber
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateTrip:(nullable GMTSTrip *)trip
updatedPropertyFields:(GMTSTripPropertyFields)updatedPropertyFields {
// Update the UI with the new `trip` data.
[self updateUIWithTrip:trip];
...
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdateTripStatus:(enum GMTSTripStatus)tripStatus {
// Handle trip status did change.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateActiveRoute:(nullable NSArray<GMTSLatLng *> *)activeRoute {
// Handle trip route did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateVehicleLocation:(nullable GMTSVehicleLocation *)vehicleLocation {
// Handle vehicle location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdatePickupLocation:(nullable GMTSTerminalLocation *)pickupLocation {
// Handle pickup location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateDropoffLocation:(nullable GMTSTerminalLocation *)dropoffLocation {
// Handle drop off location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdatePickupETA:(NSTimeInterval)pickupETA {
// Handle the pickup ETA did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateRemainingWaypoints:(nullable NSArray<GMTSTripWaypoint *> *)remainingWaypoints {
// Handle updates to the pickup, dropoff or intermediate destinations of the trip.
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdateDropoffETA:(NSTimeInterval)dropoffETA {
// Handle the drop off ETA did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel didFailUpdateTripWithError:(nullable NSError *)error {
// Handle the error.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateIntermediateDestinations:
(nullable NSArray<GMTSTerminalLocation *> *)intermediateDestinations {
// Handle the intermediate destinations being updated.
}
…
@end
您可以随时访问行程信息,具体操作步骤如下:
调用 Android 版消费者 SDK 方法
TripModel.getTripInfo()
。调用此方法不会强制进行数据刷新,但数据仍会继续以刷新频率进行刷新。获取 iOS 版消费者 SDK 属性
GMTCTripModel.currentTrip
。
第 7 步:在消费者应用中显示历程
您可以按如下方式访问 Rides 和 Deliveries 界面元素 API:
获取 Consumer SDK for Android
ConsumerController
对象。如需了解详情,请参阅使用界面元素 API。获取 iOS 版消费者 SDK
GMTCMapView
对象。如需了解详情,请参阅使用界面元素 API。
示例
以下代码示例演示了如何开始体验共享界面。
Java
JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
consumerController.showSession(session);
Kotlin
val session = JourneySharingSession.createInstance(tripModel)
consumerController.showSession(session)
Swift
let journeySharingSession = GMTCJourneySharingSession(tripModel: tripModel)
mapView.show(journeySharingSession)
Objective-C
GMTCJourneySharingSession *journeySharingSession =
[[GMTCJourneySharingSession alloc] initWithTripModel:tripModel];
[self.mapView showMapViewSession:journeySharingSession];
示例场景
假设有一辆背靠背的行程,在这种行程中,车辆已经接上了首次行程的消费者。当前行程完成时,如果驾驶员收到接其他消费者的请求,车辆正在前往下车点。
此时,首次行程的消费者会看到以下内容。
在同一时间点,第二次行程的消费者看到以下内容。
默认情况下,Consumer SDK 仅显示路线中的活动路程,但您可以选择显示其余路程(包括目的地)。
如果要显示其他行程中的航点信息,您可以按如下方式访问与行程相关的所有航点:
调用 Android 版消费者 SDK 方法
TripModel.getTripInfo()
。然后,调用TripInfo.getRemainingWaypoints()
以获取TripWaypoint
。每个TripWaypoint
对象都包含行程 ID、航点位置和航点类型。获取 iOS 版消费者 SDK 属性
GMTCTripModel.currentTrip
。然后,获取GMTSTrip.remainingWaypoints
数组以访问GMTSTripWaypoint
。每个GMTSTripWaypoint
对象都包含行程 ID、航点位置和航点类型。
第 8 步:在 Fleet Engine 中管理行程状态
您可以使用其中一个 TripStatus
枚举值指定行程状态。当行程的状态发生变化(例如,从 ENROUTE_TO_PICKUP
更改为 ARRIVED_AT_PICKUP
)时,您必须通过 Fleet Engine 更新行程状态。行程状态始终以 NEW
值开始,以 COMPLETE
或 CANCELED
值结束。如需了解详情,请参阅 trip_status
。
示例
以下后端集成示例演示了如何更新 Fleet Engine 中的行程状态。
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
static final String TRIP_ID = "trip-8241890";
String tripName = "providers/" + PROJECT_ID + "/trips/" + TRIP_ID;
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
// Trip settings to be updated.
Trip trip = Trip.newBuilder()
.setTripStatus(TripStatus.ARRIVED_AT_PICKUP)
.build();
// Trip update request
UpdateTripRequest updateTripRequest = UpdateTripRequest.newBuilder()
.setName(tripName)
.setTrip(trip)
.setUpdateMask(FieldMask.newBuilder().addPaths("trip_status"))
.build();
// Error handling.
try {
Trip updatedTrip = tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case NOT_FOUND: // The trip doesn't exist.
break;
case FAILED_PRECONDITION: // The given trip status is invalid.
break;
case PERMISSION_DENIED:
break;
}
return;
}