Следите за поездкой на Android

Выберите платформу: Android iOS JavaScript

Когда вы отслеживаете поездку, ваше приложение отображает потребителю местоположение соответствующего транспортного средства. Для этого приложению необходимо начать отслеживать поездку, обновить ход поездки и прекратить отслеживать поездку после её завершения.

В этом документе описывается, как работает этот процесс.

Прежде чем начать

Убедитесь, что вы настроили следующее:

  • Серверные службы для вашего потребительского приложения готовы к работе, а ваши службы по сопоставлению потребителей с транспортными средствами работают.

  • Вы настроили карту для своего приложения.

Начать следить за поездкой

Когда ваш внутренний сервер сопоставляет потребителя с транспортным средством, используйте JourneySharingSession , чтобы начать отслеживать поездку.

В следующем примере кода показано, как начать отслеживать поездку после загрузки представления.

Ява

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

Котлин

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 .

    Ява

    // 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) {
          // ...
    }
    
    // ...
    });
    

    Котлин

    // 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 .

    Ява

    // Set refresh interval to 2 seconds.
    TripModelOptions tripOptions =
          TripModelOptions.builder().setRefreshIntervalMillis(2000).build();
    tripModel.setTripModelOptions(tripOptions);
    

    Котлин

    // Set refresh interval to 2 seconds.
    val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build()
    tripModel.setTripModelOptions(tripOptions)
    

Остановить отслеживание поездки

Убедитесь, что ваше приложение прекращает отслеживание поездки, когда она больше не нужна, например, когда водитель отмечает поездку как ЗАВЕРШЕННУЮ на бэкенде. Остановка обмена поездками позволяет избежать ненужных сетевых запросов к Fleet Engine и предотвращает утечки памяти.

Используйте JourneySharingSession , чтобы остановить отслеживание поездки, как показано в следующем примере кода.

Ява

public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {

  // Class implementation

  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}

Котлин

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

Обработка ошибок поездки

Метод onTripRefreshError выявляет ошибки, возникающие во время мониторинга поездок. Сообщения об ошибках соответствуют стандарту Google Cloud Error. Подробные определения сообщений об ошибках и все коды ошибок см. в документации Google Cloud Errors .

Вот некоторые распространенные ошибки, которые могут возникнуть при мониторинге поездки:

HTTP RPC Описание
400 НЕВЕРНЫЙ_АРГУМЕНТ Клиент указал недопустимое название поездки. Название поездки должно иметь формат providers/{provider_id}/trips/{trip_id} . В качестве provider_id должен быть указан идентификатор облачного проекта, принадлежащего поставщику услуг.
401 НЕ ПОДТВЕРЖДЕНО Эта ошибка возникает, если отсутствуют действительные учётные данные аутентификации. Например, если токен JWT подписан без идентификатора поездки или срок действия токена JWT истёк.
403 ДОСТУП ЗАПРЕЩЕН Эта ошибка возникает, если у клиента недостаточно прав (например, пользователь с ролью потребителя пытается вызвать updateTrip), если токен JWT недействителен или API не включен для клиентского проекта. Возможно, токен JWT отсутствует или токен подписан идентификатором поездки, не соответствующим запрошенному идентификатору поездки.
429 RESOURCE_EXHAUSTED Квота ресурсов равна нулю или скорость трафика превышает лимит.
503 НЕДОСТУПНО Сервис недоступен. Обычно сервер не работает.
504 DEADLINE_EXCEEDED Превышен срок выполнения запроса. Эта ошибка возникает только в том случае, если вызывающий объект устанавливает срок, который короче срока выполнения метода по умолчанию (то есть запрошенного срока недостаточно для обработки запроса сервером), и запрос не был завершён в установленный срок.

Обработка ошибок Consumer SDK

Consumer SDK отправляет ошибки обновления данных о поездках в приложение Consumer с помощью механизма обратного вызова. Параметр обратного вызова имеет тип возвращаемого значения, зависящий от платформы ( TripUpdateError на Android и NSError на iOS).

Извлечь коды статуса

Ошибки, передаваемые в функцию обратного вызова, обычно являются ошибками gRPC, и вы также можете извлечь из них дополнительную информацию в виде кода состояния. Полный список кодов состояния см. в разделе Коды состояния и их использование в gRPC .

Ява

Вы можете извлечь код состояния gRPC, содержащий подробную информацию об ошибке, из TripUpdateError , возвращаемого onTripUpdateError() .

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

Котлин

Вы можете извлечь код состояния gRPC, содержащий подробную информацию об ошибке, из TripUpdateError , возвращаемого onTripUpdateError() .

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

Интерпретировать коды статуса

Коды состояния охватывают два вида ошибок: ошибки, связанные с сервером и сетью, и ошибки на стороне клиента.

Ошибки сервера и сети

Следующие коды состояния соответствуют ошибкам сети или сервера, и вам не нужно предпринимать никаких действий для их устранения. Consumer SDK автоматически устраняет их.

Код статуса Описание
ПРЕРВАНО Сервер перестал отправлять ответ. Обычно это вызвано проблемами на сервере.
ОТМЕНЕНО Сервер прервал исходящий ответ. Обычно это происходит, когда
приложение отправляется в фоновый режим или когда происходит изменение состояния
Потребительское приложение.
ПРЕРВАН
DEADLINE_EXCEEDED Сервер слишком долго не отвечал.
НЕДОСТУПНО Сервер был недоступен. Обычно это происходит из-за проблем с сетью.

Ошибки клиента

Следующие коды состояния относятся к ошибкам клиента, и вам необходимо принять меры для их устранения. Consumer SDK продолжит попытки обновить данные о поездке, пока вы не завершите обмен данными о поездке, но не восстановится, пока вы не примете меры.

Код статуса Описание
НЕВЕРНЫЙ_АРГУМЕНТ Приложение Consumer указало недопустимое название поездки. Название поездки должно иметь формат providers/{provider_id}/trips/{trip_id} .
НЕ НАЙДЕНО Поездка так и не была реализована.
ДОСТУП ЗАПРЕЩЕН У приложения Consumer недостаточно прав. Эта ошибка возникает, когда:
  • Приложение Consumer не имеет разрешений
  • Consumer SDK не включен для проекта в Google Cloud Console.
  • Токен JWT отсутствует или недействителен.
  • Токен JWT подписан идентификатором поездки, который не соответствует запрошенной поездке.
RESOURCE_EXHAUSTED Квота ресурсов равна нулю, или скорость транспортного потока превышает ограничение скорости.
НЕ ПОДТВЕРЖДЕНО Запрос не прошёл аутентификацию из-за недействительного токена JWT. Эта ошибка возникает, если токен JWT подписан без идентификатора поездки или если срок действия токена JWT истёк.