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