Tạo và hiển thị một chuyến đi đến một điểm đến

Tài liệu hướng dẫn này sẽ chỉ cho bạn quy trình tạo một chuyến đi bằng một lần đến lấy hàng và trả xe, sau đó chia sẻ hành trình đó với người tiêu dùng.

Điều kiện tiên quyết

Để xem hết hướng dẫn này, hãy nhớ hoàn tất các bước sau:

  1. Thiết lập Fleet Engine. Để biết thêm thông tin, hãy xem phần Fleet Engine: Thiết lập ban đầu.

  2. Tích hợp ứng dụng của bạn với SDK trình điều khiển. Để biết thêm thông tin, hãy xem phần Khởi chạy SDK trình điều khiển cho Android và Hướng dẫn tích hợp SDK trình điều khiển cho iOS.

  3. Tích hợp ứng dụng dành cho người tiêu dùng với SDK người tiêu dùng. Để biết thêm thông tin, hãy xem các bài viết Bắt đầu với SDK người tiêu dùng cho Android và Làm quen với SDK người tiêu dùng cho iOS.

  4. Thiết lập mã thông báo uỷ quyền. Để biết thêm thông tin về mã thông báo uỷ quyền, hãy xem phần Tạo mã thông báo web JSON để uỷ quyền trong hướng dẫn Bắt đầu sử dụng Fleet Engine và Xác thực và uỷ quyền trong tài liệu về Consumer SDK cho Fleet Engine.

Bước 1. Tạo xe trong Fleet Engine

Phương tiện vận chuyển là đồ vật đại diện cho phương tiện trong nhóm phương tiện của bạn. Bạn phải tạo chúng trong Fleet Engine để có thể theo dõi chúng trong ứng dụng cho người dùng thông thường.

Bạn có thể tạo xe bằng một trong hai phương pháp sau:

gRPC
Gọi phương thức CreateVehicle() bằng thông báo yêu cầu CreateVehicleRequest. Bạn phải có đặc quyền Người dùng cấp cao của Fleet Engine để gọi được CreateVehicle().
Kiến trúc chuyển trạng thái đại diện (REST)
Gọi https://fleetengine.googleapis.com/v1/providers.vehicles.create.

Chú ý

Những điều cần lưu ý sau đây sẽ áp dụng khi bạn tạo phương tiện di chuyển.

  • Hãy nhớ đặt trạng thái ban đầu của xe thành OFFLINE. Điều này đảm bảo rằng Fleet Engine có thể tìm ra xe của bạn để so khớp chuyến đi.

  • provider_id của xe phải giống với mã dự án của dự án Google Cloud chứa Tài khoản dịch vụ dùng để gọi Fleet Engine. Mặc dù nhiều tài khoản dịch vụ có thể truy cập vào Fleet Engine cho cùng một nhà cung cấp dịch vụ đi chung xe, nhưng Fleet Engine hiện không hỗ trợ tài khoản dịch vụ từ nhiều Dự án Google Cloud khác nhau sử dụng cùng một xe.

  • Phản hồi được trả về từ CreateVehicle() chứa thực thể Vehicle. Thực thể này sẽ bị xoá sau 7 ngày nếu không được cập nhật bằng UpdateVehicle(). Bạn nên gọi GetVehicle() trước khi gọi CreateVehicle() để xác nhận rằng chưa có xe này. Nếu GetVehicle() trả về lỗi NOT_FOUND, thì bạn nên tiếp tục gọi CreateVehicle(). Để biết thêm thông tin, hãy xem bài viết Phương tiện và vòng đời của chúng.

Ví dụ:

Mã mẫu nhà cung cấp sau đây minh hoạ cách tạo một chiếc xe trong 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;
}

Bước 2. Bật tính năng theo dõi vị trí

Tính năng theo dõi vị trí là hoạt động theo dõi vị trí của xe trong suốt chuyến đi, khi ứng dụng người lái gửi dữ liệu đo từ xa đến Fleet Engine, nơi chứa thông tin vị trí hiện tại của xe. Luồng thông tin vị trí được cập nhật liên tục này được dùng để truyền đạt tiến trình của xe trong suốt tuyến đường của chuyến đi. Khi bạn bật tính năng theo dõi vị trí, ứng dụng dành cho người lái xe sẽ bắt đầu gửi dữ liệu đo từ xa này với tần suất mặc định là 5 giây một lần.

Bạn bật tính năng theo dõi vị trí cho Android và iOS như sau:

Ví dụ:

Ví dụ về mã sau đây minh hoạ cách bật tính năng theo dõi vị trí.

Java

RidesharingVehicleReporter vehicleReporter = ...;

vehicleReporter.enableLocationTracking();

Kotlin

val vehicleReporter = ...

vehicleReporter.enableLocationTracking()

Swift

vehicleReporter.locationTrackingEnabled = true

Objective-C

_vehicleReporter.locationTrackingEnabled = YES;

Bước 3. Đặt trạng thái xe thành trực tuyến

Bạn đưa một chiếc xe vào dịch vụ (tức là để xe có thể sử dụng) bằng cách đặt trạng thái của xe thành trực tuyến, nhưng bạn không thể thực hiện việc này cho đến khi đã bật tính năng theo dõi vị trí.

Bạn đặt trạng thái của xe thành trực tuyến đối với Android và iOS như sau:

Ví dụ:

Mã ví dụ sau đây minh hoạ cách đặt trạng thái của xe thành ONLINE.

Java

vehicleReporter.setVehicleState(VehicleState.ONLINE);

Kotlin

vehicleReporter.setVehicleState(VehicleState.ONLINE)

Swift

vehicleReporter.update(.online)

Objective-C

[_vehicleReporter updateVehicleState:GMTDVehicleStateOnline];

Bước 4. Tạo chuyến đi trong Fleet Engine

Về mặt lập trình, Trip là một đối tượng đại diện cho một hành trình và bạn phải tạo một đối tượng cho từng yêu cầu chuyến đi để có thể so khớp với các xe và theo dõi hành trình đó.

Thuộc tính bắt buộc

Các trường sau đây là trường bắt buộc để tạo chuyến đi.

parent
Một chuỗi chứa mã nhà cung cấp. Mã này phải giống với mã dự án của dự án trên Google Cloud chứa Tài khoản dịch vụ dùng để gọi Fleet Engine
trip_id
Một chuỗi do bạn tạo để xác định duy nhất chuyến đi này.
trip_type
Một trong các giá trị liệt kê TripType (SHARED hoặc EXCLUSIVE).
pickup_point
Điểm xuất phát của chuyến đi.

Khi tạo một chuyến đi, bạn có thể cung cấp các trường number_of_passengers, dropoff_pointvehicle_id, mặc dù các trường này là không bắt buộc. Khi bạn cung cấp vehicle_id, chuyến đi sẽ chứa danh sách các điểm tham chiếu còn lại mà bạn có thể sử dụng để đặt điểm đến trong ứng dụng trình điều khiển.

Ví dụ:

Ví dụ sau đây minh hoạ cách tạo chuyến đi đến Grand Indonesia East Mall. Chuyến đi này có hai hành khách. Đây là chuyến đi riêng biệt và trạng thái là mới. provider_id của chuyến đi phải giống với mã dự án. Trong ví dụ này, nhà cung cấp dịch vụ đi chung xe đã tạo một Dự án Google Cloud có mã dự án my-rideshare-co-gcp-project. Dự án này phải bao gồm một tài khoản dịch vụ để gọi 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;
}

Bước 5. Đặt điểm đến trong ứng dụng trình điều khiển

Sau khi ghép nối người tiêu dùng với người lái xe, bạn phải định cấu hình điểm đến của chuyến đi trong ứng dụng người lái xe. Bạn có thể truy xuất điểm đến của xe từ bộ sưu tập điểm tham chiếu mà GetTrip(), UpdateTrip()GetVehicle() trả về.

  • Bạn đặt đích đến bằng cách gọi phương thức SDK điều hướng cho Android setDestination() hoặc gọi phương thức SDK điều hướng cho iOS setDestinations().

Để ứng dụng của người dùng hiển thị chính xác chuyến đi, toạ độ địa lý (LatLng) được cung cấp cho setDestination() phải khớp với các toạ độ trong điểm tham chiếu của chuyến đi. Để biết thêm thông tin, hãy xem các hướng dẫn Định tuyến tới một đích đến duy nhấtChuyển đến nhiều đích đến.

Ví dụ:

Mã mẫu sau đây minh hoạ cách đặt đích đến trong ứng dụng trình điều khiển.

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;
                             }];
}

Bước 6. Theo dõi thông tin cập nhật về chuyến đi trong ứng dụng dành cho người tiêu dùng

  • Đối với Android, bạn có thể theo dõi thông tin cập nhật dữ liệu của một chuyến đi bằng cách lấy đối tượng TripModel từ TripModelManager và đăng ký trình nghe TripModelCallback.

  • Đối với iOS, bạn có thể theo dõi thông tin cập nhật về dữ liệu của một chuyến đi bằng cách lấy đối tượng GMTCTripModel từ GMTCTripService và đăng ký một người đăng ký GMTCTripModelSubscriber.

Trình nghe TripModelCallback và người đăng ký GMTCTripModelSubscriber cho phép ứng dụng của bạn nhận thông tin cập nhật định kỳ về tiến trình chuyến đi trong mỗi lần làm mới dựa trên khoảng thời gian tự động làm mới. Chỉ những giá trị thay đổi mới có thể kích hoạt lệnh gọi lại. Nếu không, lệnh gọi lại sẽ vẫn ở chế độ im lặng.

Phương thức TripModelCallback.onTripUpdated()tripModel(_:didUpdate:updatedPropertyFields:) luôn được gọi, bất kể có thay đổi nào về dữ liệu.

Ví dụ 1

Mã mẫu sau đây minh hoạ cách lấy TripModel từ TripModelManager/GMTCTripService và thiết lập trình nghe trên đó.

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];

Ví dụ 2

Mã mẫu sau đây minh hoạ cách thiết lập trình nghe TripModelCallback và người đăng ký 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

Bạn có thể truy cập thông tin về chuyến đi bất cứ lúc nào như sau:

  • Gọi phương thức SDK người dùng cho Android TripModel.getTripInfo(). Việc gọi phương thức này sẽ không buộc làm mới dữ liệu, mặc dù dữ liệu vẫn tiếp tục được làm mới ở tần suất làm mới.

  • Tải thuộc tính SDK người tiêu dùng cho iOS GMTCTripModel.currentTrip.

Bước 7. Cập nhật chuyến đi bằng mã xe

Bạn phải định cấu hình chuyến đi bằng mã xe để Fleet Engine có thể theo dõi xe dọc theo tuyến đường.

  • Bạn có thể cập nhật chuyến đi với mã xe bằng cách gọi điểm cuối UpdateTrip bằng UpdateTripRequest. Sử dụng trường update_mask để chỉ định rằng bạn đang cập nhật mã xe.

Ghi chú

  • Nếu không chỉ định điểm đến khi tạo chuyến đi, bạn luôn có thể thực hiện tại đây.

  • Nếu cần thay đổi phương tiện trong một chuyến đi đang diễn ra, bạn phải đặt trạng thái của chuyến đi thành mới, sau đó cập nhật chuyến đi (như bạn đã làm ở trên) bằng mã xe mới.

Ví dụ:

Mã mẫu sau đây minh hoạ cách cập nhật chuyến đi bằng mã xe.

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;
}

Bước 8. Hiển thị hành trình trong ứng dụng của người tiêu dùng

Sử dụng đối tượng ConsumerController để truy cập vào các API thành phần giao diện người dùng của Rides and Deliveries.

Để biết thêm thông tin, hãy xem bài viết Sử dụng API phần tử trên giao diện người dùng.

Ví dụ:

Ví dụ về mã sau đây minh hoạ cách bắt đầu giao diện người dùng chia sẻ hành trình.

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];

Bước 9. Quản lý trạng thái chuyến đi trong Fleet Engine

Bạn chỉ định trạng thái của chuyến đi bằng một trong các giá trị liệt kê TripStatus. Khi trạng thái của chuyến đi thay đổi (ví dụ: thay đổi từ ENROUTE_TO_PICKUP thành ARRIVED_AT_PICKUP), bạn phải cập nhật trạng thái chuyến đi thông qua Fleet Engine. Trạng thái chuyến đi luôn bắt đầu bằng giá trị NEW và kết thúc bằng giá trị COMPLETE hoặc CANCELED. Để biết thêm thông tin, hãy xem trip_status.

Ví dụ:

Mã mẫu sau đây minh hoạ cách cập nhật trạng thái chuyến đi trong 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;
}