本教程将引导您完成创建只有一次上车和下车的行程,然后与消费者分享该行程的过程。
前提条件
如需完成本教程,请务必完成以下操作:
设置 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;
}
第 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
是一个表示行程的对象,并且您必须为每个行程请求创建一个对象,以便将其与车辆匹配,然后进行跟踪。
- 您可以通过使用
CreateTripRequest
请求消息调用CreateTrip()
方法来创建行程。
必需属性
以下字段是创建行程的必填字段。
parent
- 一个包含提供方 ID 的字符串。此值必须与用于调用 Fleet Engine 的服务账号所属 Google Cloud 项目的项目 ID 相同
trip_id
- 您创建的字符串,用于唯一标识此行程。
trip_type
- 其中一个
TripType
枚举值(SHARED
或EXCLUSIVE
)。 pickup_point
- 行程的出发地。
创建行程时,您可以提供 number_of_passengers
、dropoff_point
和 vehicle_id
,但这些字段并非必需字段。如果您提供 vehicle_id
,行程会包含剩余航点的列表,您可以使用这些航点在驾驶员应用中设置目的地。
示例
以下示例演示了如何创建去往 Grand Indonesia 东购物中心的行程。此行程涉及两名乘客,此行程是专有的,其状态为 new。行程的 provider_id
必须与项目 ID 相同。在本示例中,拼车服务提供商使用项目 ID my-rideshare-co-gcp-project
创建了 Google Cloud 项目。此项目必须包含用于调用 Fleet Engine 的服务帐号。
static final String PROJECT_ID = "my-rideshare-co-gcp-project";
TripServiceBlockingStub tripService = TripService.newBlockingStub(channel);
// Trip initial settings.
String parent = "providers/" + PROJECT_ID;
Trip trip = Trip.newBuilder()
.setTripType(TripType.EXCLUSIVE) // Use TripType.SHARED for carpooling.
.setPickupPoint( // Grand Indonesia East Mall.
TerminalLocation.newBuilder().setPoint(
LatLng.newBuilder()
.setLatitude(-6.195139).setLongitude(106.820826)))
.setNumberOfPassengers(2)
// Provide the drop-off point if available.
.setDropoffPoint(
TerminalLocation.newBuilder().setPoint(
LatLng.newBuilder()
.setLatitude(-6.1275).setLongitude(106.6537)))
.build();
// Create trip request
CreateTripRequest createTripRequest = CreateTripRequest.newBuilder()
.setParent(parent)
.setTripId("trip-8241890") // Trip ID assigned by the provider.
.setTrip(trip) // The initial state is NEW.
.build();
// Error handling.
try {
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 步:在驾驶员应用中设置目的地
将消费者与司机配对后,您必须在驾驶员应用中配置行程的目的地。您可以从车辆的航点集合(由 GetTrip()
、UpdateTrip()
和 GetVehicle()
返回)中检索车辆的目的地。
- 您可以通过调用 Navigation SDK for Android 方法
setDestination()
或调用 Navigation SDK for iOS 方法setDestinations()
来设置目的地。
为了让消费者应用正确渲染行程,提供给 setDestination()
的地理坐标 (LatLng) 必须与行程航点中的地理坐标 (LatLng) 一致。如需了解详情,请参阅路由到单个目的地和路由到多个目的地教程。
示例
以下代码示例演示了如何在驾驶员应用中设置目的地。
Java
private void navigateToPlace(String placeId, RoutingOptions travelMode) {
Waypoint destination;
try {
destination = Waypoint.fromPlaceId(placeId, null);
} catch (Waypoint.UnsupportedPlaceIdException e) {
displayMessage("Error starting navigation: Place ID is not supported.");
return;
}
// Create a future to await the result of the asynchronous navigator task.
ListenableResultFuture<Navigator.RouteStatus> pendingRoute =
mNavigator.setDestination(destination, travelMode);
// Define the action to perform when the SDK has determined the route.
pendingRoute.setOnResultListener(
new ListenableResultFuture.OnResultListener<Navigator.RouteStatus>() {
@Override
public void onResult(Navigator.RouteStatus code) {
switch (code) {
case OK:
// Hide the toolbar to maximize the navigation UI.
if (getActionBar() != null) {
getActionBar().hide();
}
// Enable voice audio guidance (through the device speaker).
mNavigator.setAudioGuidance(
Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE);
// Simulate vehicle progress along the route for demo/debug builds.
if (BuildConfig.DEBUG) {
mNavigator.getSimulator().simulateLocationsAlongExistingRoute(
new SimulationOptions().speedMultiplier(5));
}
// Start turn-by-turn guidance along the current route.
mNavigator.startGuidance();
break;
// Handle error conditions returned by the navigator.
case NO_ROUTE_FOUND:
displayMessage("Error starting navigation: No route found.");
break;
case NETWORK_ERROR:
displayMessage("Error starting navigation: Network error.");
break;
case ROUTE_CANCELED:
displayMessage("Error starting navigation: Route canceled.");
break;
default:
displayMessage("Error starting navigation: "
+ String.valueOf(code));
}
}
});
}
Kotlin
private fun navigateToPlace(placeId: String, travelMode: RoutingOptions) {
val destination =
try {
Waypoint.fromPlaceId(placeId, null)
} catch (e: Waypoint.UnsupportedPlaceIdException) {
displayMessage("Error starting navigation: Place ID is not supported.")
return@navigateToPlace
}
// Create a future to await the result of the asynchronous navigator task.
val pendingRoute = mNavigator.setDestination(destination, travelMode)
// Define the action to perform when the SDK has determined the route.
pendingRoute.setOnResultListener(
object : ListenableResultFuture.OnResultListener<Navigator.RouteStatus>() {
override fun onResult(code: Navigator.RouteStatus) {
when (code) {
Navigator.RouteStatus.OK -> {
// Hide the toolbar to maximize the navigation UI.
getActionBar()?.hide()
// Enable voice audio guidance (through the device speaker).
mNavigator.setAudioGuidance(Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE)
// Simulate vehicle progress along the route for demo/debug builds.
if (BuildConfig.DEBUG) {
mNavigator
.getSimulator()
.simulateLocationsAlongExistingRoute(SimulationOptions().speedMultiplier(5))
}
// Start turn-by-turn guidance along the current route.
mNavigator.startGuidance()
}
Navigator.RouteStatus.NO_ROUTE_FOUND -> {
displayMessage("Error starting navigation: No route found.")
}
Navigator.RouteStatus.NETWORK_ERROR -> {
displayMessage("Error starting navigation: Network error.")
}
Navigator.RouteStatus.ROUTE_CANCELED -> {
displayMessage("Error starting navigation: Route canceled.")
}
else -> {
displayMessage("Error starting navigation: ${code.name}")
}
}
}
}
)
}
Swift
private func startNavigation() {
let destinations = [
GMSNavigationWaypoint(
placeID: "ChIJnUYTpNASkFQR_gSty5kyoUk", title: "PCC Natural Market"),
GMSNavigationWaypoint(
placeID: "ChIJJ326ROcSkFQRBfUzOL2DSbo", title: "Marina Park"),
]
mapView.navigator?.setDestinations(destinations, callback: { routeStatus in
guard routeStatus == .OK else {
// Error starting navigation.
return
}
mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
mapView.navigator?.isGuidanceActive = true
mapView.navigator?.sendsBackgroundNotifications = true
mapView.cameraMode = .following
})
}
Objective-C
- (void)startNavigation {
NSArray<GMSNavigationWaypoint *> *destinations =
@[[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJnUYTpNASkFQR_gSty5kyoUk"
title:@"PCC Natural Market"],
[[GMSNavigationWaypoint alloc] initWithPlaceID:@"ChIJJ326ROcSkFQRBfUzOL2DSbo"
title:@"Marina Park"]];
[_mapView.navigator setDestinations:destinations
callback:^(GMSRouteStatus routeStatus) {
if (routeStatus != GMSRouteStatusOK) {
// Error starting navigation.
return;
}
[_mapView.locationSimulator simulateLocationsAlongExistingRoute];
_mapView.navigator.guidanceActive = YES;
_mapView.navigator.sendsBackgroundNotifications = YES;
_mapView.cameraMode = GMSNavigationCameraModeFollowing;
}];
}
第 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 步:使用车辆 ID 更新行程
您必须使用车辆 ID 配置行程,以便 Fleet Engine 可以沿路线跟踪车辆。
- 您可以通过使用
UpdateTripRequest
调用UpdateTrip
端点,使用车辆 ID 更新行程。使用update_mask
字段指定您要更新车辆 ID。
备注
如果您在创建行程时未指定目的地,可以随时在此处指定。
如果您需要更改进行中的行程中的车辆,则必须将行程的状态重新设置为新,然后使用新车辆 ID 更新行程(如上文所述)。
示例
以下代码示例演示了如何使用车辆 ID 更新行程。
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);
// The trip settings to update.
Trip trip = Trip.newBuilder()
.setVehicleId("8241890")
.build();
// The trip update request.
UpdateTripRequest updateTripRequest =
UpdateTripRequest.newBuilder() // No need for the header.
.setName(tripName)
.setTrip(trip)
.setUpdateMask(FieldMask.newBuilder().addPaths("vehicle_id"))
.build();
// Error handling.
// If the Fleet Engine has both a trip and vehicle with IDs, and if the
// credentials validate, then the service updates the trip.
try {
Trip updatedTrip = tripService.updateTrip(updateTripRequest);
} catch (StatusRuntimeException e) {
Status s = e.getStatus();
switch (s.getCode()) {
case NOT_FOUND: // Neither the trip nor vehicle exist.
break;
case PERMISSION_DENIED:
break;
}
return;
}
第 8 步:在消费者应用中显示历程
使用 ConsumerController
对象访问 Rides 和 Deliveries 界面元素 API。
如需了解详情,请参阅使用界面元素 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];
第 9 步:在 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;
}