Как следить за поездкой на устройстве 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();
    }
  }
}

Kotlin

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

    Kotlin

    // 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);
    

    Kotlin

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

Kotlin

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

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

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

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

HTTP Доход от клика Описание
400 INVALID_ARGUMENT Клиент указал недопустимое название поездки. Название поездки должно быть указано в формате providers/{provider_id}/trips/{trip_id}. В поле provider_id должен быть указан идентификатор облачного проекта, принадлежащего поставщику услуг.
401 UNAUTHENTICATED Эта ошибка возникает, если нет действительных учетных данных для аутентификации. Например, если токен JWT подписан без идентификатора поездки или срок действия токена JWT истек.
403 PERMISSION_DENIED Эта ошибка возникает, если у клиента недостаточно разрешений (например, пользователь с ролью потребителя пытается вызвать updateTrip), если токен JWT недействителен или если API не включен для проекта клиента. Токен JWT может отсутствовать или быть подписан с идентификатором поездки, который не соответствует запрошенному.
429 RESOURCE_EXHAUSTED Квота на ресурсы равна нулю или трафик превышает лимит.
503 UNAVAILABLE Сервис недоступен. Обычно это означает, что сервер не работает.
504 DEADLINE_EXCEEDED Превышен срок выполнения запроса. Эта ошибка возникает, только если вызывающий абонент устанавливает срок, который короче срока по умолчанию для метода (то есть запрошенного срока недостаточно для обработки запроса сервером), и запрос не был завершен в течение этого срока.

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

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

Kotlin

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

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

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

Коды статуса охватывают два типа ошибок: ошибки сервера и сети, а также ошибки на стороне клиента.

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

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

Код статусаОписание
ABORTED Сервер прекратил отправку ответа. Обычно это связано с проблемой на сервере.
ОТМЕНЕН Сервер прервал исходящий ответ. Обычно это происходит, когда приложение переходит в фоновый режим или когда меняется состояние приложения для пользователей.

INTERRUPTED
DEADLINE_EXCEEDED Сервер слишком долго отвечал.
UNAVAILABLE Сервер был недоступен. Обычно это связано с проблемами в сети.

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

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

Код статусаОписание
INVALID_ARGUMENT Приложение для пользователей указало недопустимое название поездки. Название поездки должно соответствовать формату providers/{provider_id}/trips/{trip_id}.
NOT_FOUND Поездка не была создана.
PERMISSION_DENIED У приложения для пользователей недостаточно разрешений. Эта ошибка возникает в следующих случаях:
  • У приложения для пользователей нет разрешений
  • Consumer SDK не включен для проекта в Google Cloud Console.
  • Токен JWT отсутствует или недействителен.
  • Токен JWT подписан с идентификатором поездки, который не соответствует запрошенной поездке.
RESOURCE_EXHAUSTED Квота на ресурсы равна нулю или скорость трафика превышает ограничение.
UNAUTHENTICATED Запрос не прошел аутентификацию из-за недействительного токена JWT. Эта ошибка возникает, если токен JWT подписан без идентификатора поездки или срок действия токена истек.