AI-generated Key Takeaways
- 
          Before making vehicle requests, review the requirements outlined in the Vehicle requests section of the Introduction. 
- 
          Provide vehicle location updates to Fleet Engine at least every minute and at most every 5 seconds, either using the Driver SDK (simplest) or custom code for backend integration or non-Android/iOS devices. 
- 
          Your backend is responsible for notifying Fleet Engine of vehicle status changes, including en route and arrival at stops, as this is not automatically detected. 
- 
          Vehicle location updates can be implemented using the Java gRPC library or REST, with required and optional fields for providing accurate location data and timestamps. 
Approaches
For the best performance with Fleet Engine, provide it with a stream of vehicle location updates at least once every minute and at most once every 5 seconds. Use either of the following ways to provide these updates:
- Use the Driver SDK: Simplest option.
- Use custom code: useful if locations are relayed through your backend, or if you use devices other than Android or iOS. This document covers that approach.
Regardless of how you provide vehicle location updates, your backend is responsible for updating Fleet Engine when a delivery vehicle is enroute to a stop and when it arrives at a stop. This includes the depot itself. Fleet Engine does not detect these events automatically.
Update vehicle location examples
You can use the Java gRPC library to update a vehicle's location in Fleet Engine, or use REST.
Java
  static final String PROJECT_ID = "my-delivery-co-gcp-project";
  static final String VEHICLE_ID = "vehicle-8241890";
  DeliveryServiceBlockingStub deliveryService =
    DeliveryServiceGrpc.newBlockingStub(channel);
  // Vehicle settings
  String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
  DeliveryVehicle myDeliveryVehicle = DeliveryVehicle.newBuilder()
      .setLastLocation(DeliveryVehicleLocation.newBuilder()
          .setSupplementalLocation(LatLng.newBuilder()
              .setLatitude(37.3382)
              .setLongitude(121.8863))
          .setSupplementalLocationTime(now())
          .setSupplementalLocationSensor(DeliveryVehicleLocationSensor.CUSTOMER_SUPPLIED_LOCATION)
          .setSupplementalLocationAccuracy(DoubleValue.of(15.0)))  // Optional
      .build();
  // DeliveryVehicle request
  UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
    UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
        .setName(vehicleName)
        .setDeliveryVehicle(myDeliveryVehicle)
        .setUpdateMask(FieldMask.newBuilder()
            .addPaths("last_location"))
        .build();
  try {
    DeliveryVehicle updatedDeliveryVehicle =
        deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
  } catch (StatusRuntimeException e) {
    Status s = e.getStatus();
    switch (s.getCode()) {
       case NOT_FOUND:
         break;
       case PERMISSION_DENIED:
         break;
    }
    return;
  }
REST
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=last_location
Request details
The request body must contain a DeliveryVehicle entity that specifies
fields as follows:
- Required fields: - Field - Value - lastLocation.supplementalLocation- The location of the vehicle. - lastLocation.supplementalLocationTime- The last known timestamp the vehicle was at this location. - lastLocation.supplementalLocationSensor- Should be populated with - CUSTOMER_SUPPLIED_LOCATION.
- Optional fields: - Field - Value - lastLocation.supplementalLocationAccuracy- Accuracy of the supplied location, in meters. 
  # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
  # environment
  curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
    -H "Content-type: application/json" \
    -H "Authorization: Bearer ${JWT}" \
    --data-binary @- << EOM
  {
    "lastLocation": {
      "supplementalLocation": {"latitude": 12.1, "longitude": 14.5},
      "supplementalLocationTime": "$(date -u --iso-8601=seconds)",
      "supplementalLocationSensor": "CUSTOMER_SUPPLIED_LOCATION",
      "supplementalLocationAccuracy": 15
    }
  }
  EOM