Siga uma viagem no Android

Selecione a plataforma: Android iOS JavaScript

Quando você acompanha uma viagem, o app do consumidor mostra o local do veículo apropriado para o consumidor. Para isso, o app precisa começar a acompanhar uma viagem, atualizar o progresso dela e parar de acompanhar uma viagem quando ela for concluída.

Este documento explica como esse processo funciona.

Antes de começar

Verifique se você configurou o seguinte:

  • Os serviços de back-end do app do consumidor estão em vigor, e os serviços para combinar consumidores com veículos estão operacionais.

  • Você configurou um mapa para seu app.

Começar a seguir uma viagem

Quando o servidor de back-end associa um consumidor a um veículo, use JourneySharingSession para começar a acompanhar a viagem usando o compartilhamento de jornada.

O exemplo de código a seguir demonstra como iniciar o compartilhamento da jornada após o é carregada.

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

Atualizar viagem

Atualizar detalhes do andamento da viagem, como a distância que o veículo precisa viajar antes da chegada e o horário previsto de chegada, seu app precisa registrar e configurar um listener, conforme mostrado nos exemplos a seguir.

  1. Registre um listener em um objeto 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. Configure o listener da sua viagem usando 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)
    

Parar de seguir uma viagem

Verifique se o app para de seguir uma viagem quando ela não é mais necessária, como quando a viagem é marcada como "CONCLUÍDA" no back-end pelo motorista. A interrupção do compartilhamento de jornadas evita solicitações de rede desnecessárias para o Fleet Engine e impede vazamentos de memória.

Use JourneySharingSession para parar de seguir a viagem, conforme mostrado no a seguir.

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

Processar erros de viagem

O método onTripRefreshError mostra erros que ocorrem durante a viagem e o monitoramento. As mensagens de erro seguem o padrão Google Cloud Error. Para obter definições de mensagens de erro e todos os códigos de erro, consulte a seção Erros do Google Cloud Documentação.

Confira alguns erros comuns que podem ocorrer durante o monitoramento da viagem:

HTTP RPC Descrição
400 INVALID_ARGUMENT O cliente especificou um nome de viagem inválido. O nome da viagem precisa seguir o formato providers/{provider_id}/trips/{trip_id}. O provider_id precisa ser o ID do projeto do Cloud de propriedade de o provedor de serviços.
401 UNAUTHENTICATED Você vai receber esse erro se não houver credenciais de autenticação válidas. Por exemplo, se o token JWT for assinado sem um ID de viagem ou se o token JWT tiver expirado.
403 PERMISSION_DENIED Você vai receber esse erro se o cliente não tiver permissão suficiente (por exemplo, um usuário com o papel de consumidor tenta chamar updateTrip), se o token JWT é inválido ou a API não está ativada para o projeto do cliente. O token JWT pode estar ausente ou assinado com um ID de viagem que não corresponde ao ID de viagem solicitado.
429 RESOURCE_EXHAUSTED A cota de recursos está em zero ou a taxa de tráfego excede o limite.
503 INDISPONÍVEL Serviço indisponível. Geralmente, o servidor está desativado.
504 DEADLINE_EXCEEDED O prazo de solicitação foi excedido. Esse erro só ocorre se o autor da chamada definir um prazo menor que o prazo padrão do método (ou seja, o prazo solicitado não é suficiente para o servidor processar a solicitação) e a solicitação não for concluída dentro do prazo.

Processar erros do SDK do consumidor

O SDK para o consumidor envia erros de atualização de viagem ao aplicativo do consumidor usando um callback mecanismo de atenção. O parâmetro callback é um tipo de retorno específico da plataforma ( TripUpdateError no Android, e NSError no iOS).

Extrair códigos de status

Os erros transmitidos ao callback são normalmente erros gRPC, e também é possível extrair informações adicionais deles na forma de um código de status. Para conferir a lista completa de códigos de status, consulte Códigos de status e o uso deles no gRPC.

Java

É possível extrair um código de status do gRPC que fornece detalhes sobre o erro da TripUpdateError retornada de onTripUpdateError().

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

Kotlin

Extraia um código de status gRPC que forneça detalhes sobre o erro. do valor de TripUpdateError retornado de onTripUpdateError().

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

Interpretar códigos de status

Os códigos de status abrangem dois tipos de erros: erros relacionados ao servidor e à rede e erros do lado do cliente.

Erros de servidor e de rede

Os códigos de status a seguir são para erros de rede ou de servidor, e você não precisa fazer nada para resolvê-los. O SDK para o consumidor automaticamente se recupera delas.

Código de statusDescrição
ABORTED O servidor parou de enviar a resposta. Isso geralmente é causado por um problema no servidor.
CANCELADO O servidor encerrou a resposta enviada. Isso normalmente acontece quando
o app é enviado para o segundo plano ou quando há uma mudança de estado no
app do consumidor.
INTERRUPTED
DEADLINE_EXCEEDED O servidor demorou muito para responder.
INDISPONÍVEL O servidor não estava disponível. Isso normalmente é causado por um problema de rede.

Erros do cliente

Os códigos de status a seguir são para erros do cliente, e você precisa tomar medidas para resolvê-los. O SDK para consumidores continuará tentando atualizar a viagem até que você encerrar o compartilhamento da jornada, mas ele não se recuperará até que você realize uma ação.

Código de statusDescrição
INVALID_ARGUMENT O app do consumidor especificou um nome de viagem inválido. O nome da viagem precisa seguir o formato providers/{provider_id}/trips/{trip_id}.
NOT_FOUND A viagem nunca foi criada.
PERMISSION_DENIED O app do consumidor não tem permissões suficientes. Esse erro ocorre quando:
  • O app para o consumidor não tem permissões
  • O SDK do consumidor não está ativado para o projeto no Google Cloud do Cloud.
  • O token JWT está ausente ou é inválido.
  • O token JWT é assinado com um ID de viagem que não corresponde à viagem solicitada.
RESOURCE_EXHAUSTED A cota de recursos está em zero ou a taxa do fluxo de tráfego excede a limite de velocidade.
UNAUTHENTICATED A solicitação falhou na autenticação devido a um token JWT inválido. Isso ocorre quando o token JWT é assinado sem um ID de viagem ou quando o token JWT tiver expirado.