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

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

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

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

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

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

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

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

Начните следить за путешествием

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

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

Java

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 .

    Java

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

    Java

    // 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 , чтобы остановить отслеживание поездки, как показано в следующем примере кода.

Java

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 Errors. Подробные определения сообщений об ошибках и все коды ошибок см. в документации Google Cloud Errors .

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

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

Обработка ошибок потребительского SDK

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

Извлечение кодов состояния

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

Java

Вы можете извлечь код состояния 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()
}

Интерпретация кодов состояния

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

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

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

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

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

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

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