Primeiros passos com o SDK do driver para Android

Requisitos mínimos do sistema

O dispositivo móvel precisa ter o Android 6.0 (nível 23 da API) ou mais recente.

Configuração do build e das dependências

As versões 4.99 e mais recentes do SDK do Driver estão disponíveis no repositório Maven do Google.

Gradle

Adicione a instrução a seguir ao seu arquivo build.gradle:

repositories {
    ...
    google()
}

Maven

Adicione a instrução a seguir ao seu arquivo pom.xml:

<project>
  ...
  <repositories>
    <repository>
      <id>google-maven-repository</id>
      <url>https://maven.google.com</url>
    </repository>
  </repositories>
  ...
</project>

Configuração do projeto

Para usar o SDK do Driver, o app precisa ser direcionado ao minSdkVersion 23 ou mais recente. Para mais informações, consulte as Notas de lançamento.

Para executar um app criado com o SDK do driver, o dispositivo Android precisa ter o Google Play Services instalado.

Configurar seu projeto de desenvolvimento

Para configurar o projeto de desenvolvimento e receber uma chave de API para o projeto no Console do Google Cloud:

  1. Crie um novo projeto do Console do Google Cloud ou selecione um projeto existente para usar com o SDK do Driver. Aguarde alguns minutos até que o novo projeto esteja visível no Console do Google Cloud.

  2. Para executar o app de demonstração, seu projeto precisa ter acesso ao SDK do Maps para Android. No Console do Google Cloud, selecione APIs e serviços > Biblioteca, pesquise e ative o SDK do Maps para Android.

  3. Para gerar uma chave de API para o projeto, selecione APIs e serviços > Credenciais > Criar credenciais > Chave de API. Para mais informações sobre como conseguir uma chave de API, consulte Acessar uma chave de API.

Adicionar o SDK do Driver ao seu app

O SDK do Driver está disponível no repositório Maven do Google. O repositório inclui os arquivos do Modelo de objeto de projeto (.pom) do SDK e Javadocs. Para adicionar o SDK do Driver ao seu app:

  1. Adicione a seguinte dependência à configuração do Gradle ou do Maven, substituindo o marcador VERSION_NUMBER pela versão selecionada do SDK do Driver.

    Gradle

    Adicione o seguinte ao seu build.gradle:

    dependencies {
      ...
      implementation 'com.google.android.libraries.mapsplatform.transportation:transportation-driver:[VERSION_NUMBER]'
    }
    

    Maven

    Adicione o seguinte ao seu pom.xml:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation.driver</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>[VERSION_NUMBER]</version>
      </dependency>
    </dependencies>
    
  2. O SDK Driver depende do SDK do Navigation. Essa dependência é configurada para que, se uma versão específica do SDK do Navigation seja necessária, ela precisa ser explicitamente definida no arquivo de configuração do build, como no exemplo a seguir. A omissão do bloco de código mencionado permite que o projeto sempre faça o download da versão mais recente do SDK do Navigation na versão de lançamento principal. Os comportamentos combinados das versões mais recentes dos SDKs do Driver e do Navigation foram submetidos a testes rigorosos antes do lançamento.

    Organize a configuração das dependências dos ambientes de desenvolvimento e lançamento de acordo com elas.

    Gradle

    Adicione o seguinte ao seu build.gradle:

    dependencies {
      ...
      implementation 'com.google.android.libraries.navigation:navigation:5.0.0'
    }
    

    Maven

    Adicione o seguinte ao seu pom.xml:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.navigation</groupId>
        <artifactId>navigation</artifactId>
        <version>5.0.0</version>
      </dependency>
    </dependencies>
    

Adicionar a chave de API ao seu app

Depois de adicionar o SDK do driver ao app, inclua a chave de API nele. É necessário usar a chave de API do projeto que você recebeu ao configurar seu projeto de desenvolvimento.

Nesta seção, descrevemos como armazenar sua chave de API para que ela possa ser referenciada pelo seu app com mais segurança. Não faça a verificação da sua chave de API no sistema de controle de versões. Ele precisa ser armazenado no arquivo local.properties, localizado no diretório raiz do projeto. Para saber mais sobre o arquivo local.properties, consulte Arquivos de propriedades do Gradle.

Se quiser otimizar essa tarefa, use o plug-in Secrets Gradle para Android. Siga este procedimento para instalar o plug-in Secrets Gradle e armazenar a chave de API com segurança.

  1. Abra o arquivo build.gradle no nível raiz e adicione o seguinte código ao elemento dependencies em buildscript.

    Groovy

    buildscript {
        dependencies {
            // ...
            classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0"
        }
    }
    

    Kotlin

    buildscript {
        dependencies {
            // ...
            classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.0")
        }
    }
    
  2. Abra o arquivo build.gradle no nível do app e adicione o seguinte código ao elemento plugins.

    Groovy

    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
    

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Sincronize seu projeto com o Gradle.

  4. Abra o local.properties no diretório do nível do projeto e adicione o código abaixo. Substitua YOUR_API_KEY pela sua chave de API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. No seu arquivo AndroidManifest.xml, acesse com.google.android.geo.API_KEY e atualize o atributo android:value da seguinte maneira:

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="${MAPS_API_KEY}" />
    

O exemplo a seguir mostra um manifesto completo para um app de exemplo:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.driverapidemo" >
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/_AppTheme" >

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAPS_API_KEY}" />

        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Incluir as atribuições necessárias no seu app

Se você usa o SDK do Driver no seu app, é necessário incluir texto de atribuição e licenças de código aberto como parte da seção de avisos legais do app. É melhor incluir as atribuições como um item de menu independente ou como parte de um item de menu Sobre.

As informações de licenças podem ser encontradas no arquivo "third_party_licenses.txt" no arquivo AAR desarquivado.

Consulte https://developers.google.com/android/guides/opensource para saber como incluir avisos de código aberto.

Dependências

O SDK do Driver usa o gRPC para se comunicar com o servidor do Fleet Engine. Se você ainda não usa o gRPC, pode ser necessário declarar as seguintes dependências:

dependencies {
    implementation 'io.grpc:grpc-android:1.12.0'
    implementation 'io.grpc:grpc-okhttp:1.12.0'
}

Sem essas dependências, o SDK do Driver pode encontrar erros durante a execução ao tentar se comunicar com o servidor do Fleet Engine.

Se você usa o ProGuard para otimizar seus builds, talvez seja necessário adicionar as seguintes linhas ao arquivo de configuração do ProGuard:

-dontwarn com.google.**
-dontwarn io.grpc.**
-dontwarn okio.**

O nível mínimo da API com suporte é 23.

Inicializar o SDK

Um ID de provedor (geralmente o ID do projeto do Google Cloud) é necessário para inicializar o objeto DriverContext. Para mais detalhes sobre como configurar o projeto do Google Cloud, consulte Autenticação e autorização.

Antes de usar o SDK do Driver, primeiro é necessário inicializar o SDK do Navigation. Para iniciar o SDK:

  1. Extraia um objeto Navigator do NavigationApi.

    NavigationApi.getNavigator(
        this, // Activity
        new NavigationApi.NavigatorListener() {
          @Override
          public void onNavigatorReady(Navigator navigator) {
            // Keep a reference to the Navigator (used to configure and start nav)
            this.navigator = navigator;
          }
        }
    );
    
  2. Crie um objeto DriverContext preenchendo os campos obrigatórios.

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    
  3. Use o objeto DriverContext para inicializar o *DriverApi.

    DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
    
  4. Consiga o DeliveryVehicleReporter do objeto da API. (DeliveryVehicleReporter estende NavigationVehicleReporter.)

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

Como autenticar com AuthTokenFactory

Quando o SDK do Driver gera atualizações de localização, ele precisa enviá-las ao servidor do Fleet Engine. Para autenticar essas solicitações, o SDK do Driver chama uma instância de AuthTokenFactory fornecida pelo autor da chamada. A fábrica é responsável por gerar tokens de autenticação no momento da atualização do local.

A forma exata em que os tokens são gerados é específica para cada situação de desenvolvedor. No entanto, a implementação provavelmente vai precisar:

  • buscar um token de autenticação, possivelmente no formato JSON, de um servidor HTTPS;
  • analise e armazene o token em cache
  • atualizar o token quando ele expirar;

Para detalhes sobre os tokens esperados pelo servidor do Fleet Engine, consulte Como criar um JSON Web Token (JWT) para autorização.

Confira uma implementação de esqueleto de um AuthTokenFactory:

class JsonAuthTokenFactory implements AuthTokenFactory {
  private String vehicleServiceToken;  // initially null
  private long expiryTimeMs = 0;

  // This method is called on a thread whose only responsibility is to send
  // location updates. Blocking is OK, but just know that no location updates
  // can occur until this method returns.
  @Override
  public String getToken(AuthTokenContext authTokenContext) {
    if (System.currentTimeMillis() > expiryTimeMs) {
      // The token has expired, go get a new one.
      fetchNewToken(vehicleId);
    }
    if (ServiceType.VEHICLE.equals(authTokenContext.getServiceType)) {
      return vehicleServiceToken;
    } else {
      throw new RuntimeException("Unsupported ServiceType: " + authTokenContext.getServiceType());
    }
  }

  private void fetchNewToken(String vehicleId) {
    String url = "https://yourauthserver.example/token/" + vehicleId;

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
      vehicleServiceToken = obj.get("VehicleServiceToken").getAsString();
      expiryTimeMs = obj.get("TokenExpiryMs").getAsLong();

      // The expiry time could be an hour from now, but just to try and avoid
      // passing expired tokens, we subtract 10 minutes from that time.
      expiryTimeMs -= 10 * 60 * 1000;
    } catch (IOException e) {
      // It's OK to throw exceptions here. The StatusListener you passed to
      // create the DriverContext class will be notified and passed along the failed
      // update warning.
      throw new RuntimeException("Could not get auth token", e);
    }
  }
}

Esta implementação específica usa o cliente HTTP Java integrado para buscar um token no formato JSON no servidor de autenticação do desenvolvedor. O token é salvo para reutilização. O token será buscado novamente se o token antigo estiver dentro de 10 minutos após o prazo de validade.

Sua implementação pode fazer as coisas de forma diferente, como usar uma linha de execução em segundo plano para atualizar os tokens.

As exceções em AuthTokenFactory são tratadas como temporárias, a menos que ocorram repetidamente. Após várias tentativas, o SDK do driver supõe que o erro é permanente e para de tentar enviar atualizações.

Status e relatórios de erros com StatusListener

Como o SDK do Driver executa ações em segundo plano, use o StatusListener para acionar notificações quando determinados eventos ocorrerem, como erros, avisos ou mensagens de depuração. Os erros podem ser temporários por natureza (como BACKEND_CONNECTIVITY_ERROR) ou podem causar a interrupção permanente das atualizações de local, como VEHICLE_NOT_FOUND, indicando um erro de configuração.

Você fornece uma implementação StatusListener opcional como esta:

class MyStatusListener implements StatusListener {
  /** Called when background status is updated, during actions such as location reporting. */
  @Override
  public void updateStatus(
      StatusLevel statusLevel, StatusCode statusCode, String statusMsg) {
    // Status handling stuff goes here.
    // StatusLevel may be DEBUG, INFO, WARNING, or ERROR.
    // StatusCode may be DEFAULT, UNKNOWN_ERROR, VEHICLE_NOT_FOUND,
    // BACKEND_CONNECTIVITY_ERROR, or PERMISSION_DENIED.
  }
}

Observações sobre SSL/TLS

Internamente, a implementação do SDK do Driver usa SSL/TLS para se comunicar de maneira segura com o servidor do Fleet Engine. Versões anteriores do Android (versão 23 da API ou anteriores) podem exigir um patch SecurityProvider para se comunicar com o servidor. Para mais informações sobre como trabalhar com o SSL no Android, consulte Provedor de segurança do GMS. O artigo também contém exemplos de código para corrigir o provedor de segurança.

Ativar atualizações de localização

Quando você tiver uma instância de *VehicleReporter, a ativação das atualizações de localização é simples:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

As atualizações de localização são enviadas em intervalos regulares, se possível. Cada atualização de local também indica que o veículo está on-line.

Por padrão, o intervalo do relatório é de 10 segundos. É possível alterar o intervalo de relatórios com reporter.setLocationReportingInterval(long, TimeUnit). O intervalo mínimo de atualização permitido é de cinco segundos. Atualizações mais frequentes podem resultar em solicitações mais lentas e erros.

Desativar atualizações de localização

Quando o turno do motorista terminar, você poderá interromper as atualizações de localização chamando DeliveryVehicleReporter.disableLocationTracking.

Casos de uso de modelos confiáveis

Esta seção descreve como usar o SDK do driver para implementar casos de uso comuns ao utilizar o modelo confiável.

Criar um veículo

Você pode criar um veículo no SDK do Driver.

Antes de criar um veículo, inicialize a API Delivery Driver. O ID do veículo precisa ser criado com o ID do veículo e do provedor usados durante a inicialização do SDK do Driver. Em seguida, crie o veículo conforme mostrado neste exemplo:

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleManager vehicleManager = api.getDeliveryVehicleManager();
try {
  DeliveryVehicle vehicle = vehicleManager.createVehicle().get();
  // Handle CreateVehicleRequest DeliveryVehicle response.
} catch (Exception e) {
  // Handle CreateVehicleRequest error.
}

Criar uma tarefa de retirada de remessa

É possível criar uma tarefa de retirada de remessa no SDK do motorista.

Antes de criar uma tarefa, inicialize a API Delivery Driver. A tarefa precisa ser criada usando o ID do provedor especificado durante a inicialização do SDK do driver. Em seguida, crie a tarefa de retirada do frete conforme mostrado no exemplo a seguir. Para informações sobre IDs de tarefas, consulte Exemplos de IDs de tarefas.

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
   .setTaskDurationSeconds(2 * 60)
   .setParentId("my-tracking-id")
   .setTaskType(TaskType.DELIVERY_PICKUP)
   .build();

try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

Criar uma tarefa de entrega

É possível criar uma tarefa de entrega de envio no SDK do motorista.

Antes de criar uma tarefa, inicialize a API Delivery Driver. Em seguida, crie a tarefa de entrega de remessa, conforme mostrado no exemplo a seguir. Para informações sobre IDs de tarefas, consulte Exemplos de IDs de tarefas.

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
   .setTaskDurationSeconds(2 * 60)
   .setParentId("my-tracking-id")
   .setTaskType(TaskType.DELIVERY_DELIVERY)
   .build();
try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

Indisponibilidade programada

Você pode criar uma tarefa que indica indisponibilidade (por exemplo, para motoristas ou reabastecimento de veículos) usando o SDK do Driver. Uma tarefa de indisponibilidade programada não pode incluir um ID de acompanhamento. Você também pode informar um local.

Antes de criar uma tarefa, inicialize a API Delivery Driver. Em seguida, crie a tarefa de indisponibilidade, conforme mostrado no exemplo abaixo. Para informações sobre IDs de tarefas, consulte Exemplos de IDs de tarefas.

static final String TASK_ID = "task-8241890"; // Avoid auto-incrementing IDs.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
   .setTaskDurationSeconds(2 * 60) // Duration or location (or both) must be provided for a BREAK task.
   .setTaskType(TaskType.UNAVAILABLE)
   .build();
try {
   DeliveryTask task = taskManager.createTask(request).get();
   // Handle CreateTaskRequest DeliveryTask response.
} catch (Exception e)  {
   // Handle CreateTaskRequest error.
}

Paradas programadas

Você pode criar uma tarefa de parada programada no SDK do Driver. É possível que uma tarefa de parada programada não inclua um ID de acompanhamento.

Antes de criar uma tarefa, inicialize a API Delivery Driver. Em seguida, crie a tarefa de parada programada, conforme mostrado no exemplo a seguir. Para informações sobre IDs de tarefas, consulte Exemplos de IDs de tarefas.

    static final String TASK_ID = "task-8241890"; //  Avoid auto-incrementing IDs.

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryTaskManager taskManager = api.getDeliveryTaskManager();
    CreateDeliveryTaskRequest request = CreateDeliveryTaskRequest.builder(TASK_ID)
       .setPlannedWaypoint(Waypoint.builder().setLatLng(-6.195139, 106.820826).build())
       .setTaskDurationSeconds(2 * 60)
       .setTaskType(TaskType.DELIVERY_SCHEDULED_STOP)
       .build();
    try {
       DeliveryTask task = taskManager.createTask(request).get();
       // Handle CreateTaskRequest DeliveryTask response.
    } catch (Exception e)  {
       // Handle CreateTaskRequest error.
    }

Atualizar a ordem das tarefas

Você pode atualizar a ordem de execução das tarefas atribuídas a um veículo no SDK do Driver.

A atualização da ordem de tarefas também atribui tarefas a um veículo, caso elas não tenham sido atribuídas anteriormente a um veículo. Ele também fecha tarefas que foram atribuídas anteriormente a um veículo e foram deixadas de fora da ordem atualizada. Atribuir uma tarefa a um veículo diferente, caso ela já tenha sido atribuída a outro veículo, gera um erro. Antes de atribuir uma tarefa ao novo veículo, feche a tarefa atual e crie uma nova.

Você pode atualizar a ordem das tarefas a qualquer momento.

Antes de atualizar a ordem de tarefas de um veículo, verifique se o veículo e as tarefas já foram criados no Fleet Engine. Em seguida, atualize a ordem das tarefas para o veículo, conforme mostrado no exemplo abaixo.

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
    try {
       List<VehicleStop> stops = reporter.setVehicleStops(
         ImmutableList.of(
             VehicleStop.builder()
                 .setVehicleStopState(VehicleStopState.ARRIVED)
                 .setWaypoint(Waypoint.builder().setLatLng(37.1749, 122.412).build())
                 .setTasks(ImmutableList.of(task1)) // Previously created DeliveryTask in Fleet Engine.
                 .build(),
             VehicleStop.builder()
                 .setVehicleStopState(VehicleStopState.NEW) // The current vehicle stop.
                 .setWaypoint(Waypoint.builder().setLatLng(37.7749, 122.4194).build())
                 .setTasks(ImmutableList.of(task2)) // Previously created DeliveryTask in Fleet Engine.
                 .build(),
             VehicleStop.builder()
                 .setVehicleStopState(VehicleStopState.NEW)
                 .setWaypoint(Waypoint.builder().setLatLng(37.3382, 121.8863).build())
                 .setTasks(ImmutableList.of(task3, task4)) // Previously created DeliveryTasks in Fleet Engine.
                 .build())).get();
       // Successfully updated vehicle stops in Fleet Engine. Returns the successfully set VehicleStops.
    } catch (Exception e)  {
       // Failed to update vehicle stops in Fleet Engine. Setting VehicleStops must be attempted again after resolving
       // errors.
    }

Pode ocorrer uma exceção que impede uma atualização do estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame setVehicleStops novamente até que a chamada seja concluída.

Os possíveis problemas podem incluir:

  • Os VehicleStops especificados não seguem um padrão válido. Somente o primeiro VehicleStop pode estar em qualquer um dos VehicleStopStates: NEW, ENROUTE ou ARRIVED. Os VehicleStops após a parada atual precisam estar no NOVO VehicleStopState.

  • As tarefas não existem ou pertencem a um veículo diferente.

  • O veículo não existe.

O veículo está a caminho da próxima parada

O motor da frota precisa ser notificado quando um veículo sai de uma parada e quando ele inicia a navegação. Notifique o Fleet Engine no SDK do Driver.

Antes de notificar o Fleet Engine que um veículo partiu de uma parada, verifique se as paradas do veículo foram criadas e definidas. Em seguida, notifique o Fleet Engine sobre a partida do veículo, conforme mostrado no exemplo a seguir.

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
    reporter.enableLocationTracking(); // Location tracking must be enabled.

    // Create Vehicle, VehicleStops, and DeliveryTasks.
    // Set VehicleStops on Vehicle.

    navigator.setDestination(vehicleStop.getWaypoint());
    try {
       List<VehicleStop> updatedStops = reporter.enrouteToNextStop().get();
       // Successfully updated vehicle stops in Fleet Engine. Returns the set VehicleStops, with the first
       // VehicleStop updated to ENROUTE state.
    } catch (Exception e)  {
       // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
       // after resolving errors.
    }

Pode ocorrer uma exceção que impede uma atualização no estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame enrouteToNextStop novamente até conseguir.

Os possíveis problemas podem incluir:

  • Nenhum VehicleStops restante está definido no SDK do driver.

O veículo chega a uma parada

O motor da frota precisa ser notificado quando um veículo chega a uma parada. É possível notificar o Fleet Engine pelo SDK do Driver.

Antes de notificar o Fleet Engine que um veículo chegou a uma parada, verifique se as paradas do veículo foram definidas. Em seguida, notifique o Fleet Engine sobre a chegada do veículo na parada, conforme mostrado no exemplo a seguir.

DeliveryDriverApi api = DeliveryDriverApi.getInstance();
DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
reporter.enableLocationTracking(); // Location tracking must be enabled.

// Create Vehicle, VehicleStops, and DeliveryTasks.
// Set VehicleStops on Vehicle.
// Mark ENROUTE to VehicleStop and start guidance using Navigator.

try {
   List<VehicleStop> updatedStopsArrived = reporter.arrivedAtStop().get();
   // Successfully updated vehicle stops in Fleet Engine. Returns the set VehicleStops, with the first
   // VehicleStop updated to ARRIVED state.
   navigator.clearDestinations();
} catch (Exception e)  {
   // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
   // after resolving errors.
}

Pode ocorrer uma exceção que impede uma atualização no estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame arrivedAtStop novamente até que a operação seja bem-sucedida.

Os possíveis problemas podem incluir:

  • Nenhum VehicleStops restante está definido no SDK do driver.

O veículo faz uma parada

Você precisa notificar o Fleet Engine quando um veículo concluir uma parada. Essa notificação faz com que todas as tarefas associadas à parada sejam definidas com o estado FECHADO. É possível notificar o Fleet Engine pelo SDK do Driver.

Notifica o Fleet Engine de que o veículo concluiu o VehicleStop, conforme mostrado no exemplo a seguir.

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryVehicleReporter reporter = api.getDeliveryVehicleReporter();
    reporter.enableLocationTracking(); // Location tracking must be enabled.

    // After completing the tasks at the VehicleStop, remove it from the
    // the current list of VehicleStops.

    try {
       List<VehicleStop> updatedStopsCompleted = reporter.completedStop().get();
       // Successfully updated vehicle stops in Fleet Engine. All tasks on the completed stop are set to CLOSED.
       // Returns the set VehicleStops, with the completed VehicleStop removed from the remaining list.
    } catch (Exception e)  {
       // Failed to update vehicle stops in Fleet Engine. Updating VehicleStops must be attempted again
       // after resolving errors.
    }

Pode ocorrer uma exceção que impede uma atualização no estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame completedStop novamente até que a operação seja bem-sucedida.

Os possíveis problemas podem incluir:

  • Nenhum VehicleStops restante está definido no SDK do driver.

Encerrar uma tarefa

Para fechar uma tarefa atribuída a um veículo, notifique o Fleet Engine de que o veículo concluiu a parada onde a tarefa ocorre ou remova-o da lista de paradas de veículos. Para fazer isso, defina a lista das paradas restantes do mesmo modo como ao atualizar a ordem das tarefas de um veículo.

Se uma tarefa ainda não tiver sido atribuída a um veículo e ela precisar ser fechada, atualize a tarefa para o estado CLOSED. No entanto, não é possível reabrir uma tarefa FECHADA.

Fechar uma tarefa não indica sucesso ou falha. Isso indica que a tarefa não é mais considerada em andamento. Para o rastreamento de remessa, é importante indicar o resultado real de uma tarefa para que um resultado de entrega possa ser mostrado.

Uma tarefa precisa ser atribuída a um veículo para usar o SDK do Driver para fechá-la. Para fechar uma tarefa atribuída a um veículo, notifique o Fleet Engine que o veículo concluiu a parada em que a tarefa acontece.

Como alternativa, atualize a ordem da tarefa do veículo a que a tarefa foi atribuída e remova a tarefa da lista de paradas.

Definir o resultado da tarefa e o local do resultado

Fechar uma tarefa não indica sucesso ou falha. Isso indica que a tarefa não é mais considerada em andamento. Para o rastreamento de remessa, é importante indicar o resultado real de uma tarefa para que um resultado de entrega possa ser mostrado e para que haja o faturamento adequado dos serviços. Depois de definido, não é possível mudar o resultado da tarefa. Mas você pode modificar o horário e o local do resultado da tarefa depois de configurá-los.

As tarefas no estado FECHADO podem ter o resultado definido como SUCCEEDED ou FAILED. O Fleet Engine cobra apenas tarefas de entrega com o estado SUCCEEDED.

Ao marcar o resultado de uma tarefa, o Fleet Engine preenche automaticamente o local de resultado da tarefa com o último local conhecido do veículo. É possível modificar esse comportamento.

O exemplo abaixo mostra como usar o SDK do Driver para definir o resultado da tarefa e o carimbo de data/hora. Não é possível definir o local de resultado da tarefa usando o SDK do Driver.

    static final String TASK_ID = "task-8241890";

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryTaskManager taskManager = api.getDeliveryTaskManager();

    // Updating an existing DeliveryTask which is already CLOSED. Manually
    // setting TaskOutcomeLocation with Driver SDK is not supported at this time.
    UpdateDeliveryTaskRequest req = UpdateDeliveryTaskRequest.builder(TASK_ID)
        .setTaskOutcome(TaskOutcome.SUCCEEDED)
        .setTaskOutcomeTimestamp(now()) // Timestamp in milliseconds.
        .build();

    try {
       DeliveryTask updatedTask = taskManager.updateTask(req);
       // Handle UpdateTaskRequest DeliveryTask response.
    } catch (Exception e)  {
       // Handle UpdateTaskRequest error.
    }

Procurar um veículo

É possível procurar um veículo no SDK do Driver. Antes de procurar um veículo, inicialize a API Delivery Driver. Em seguida, procure o veículo conforme mostrado no exemplo abaixo.

    DeliveryDriverApi api = DeliveryDriverApi.getInstance();
    DeliveryVehicleManager vehicleManager = api.getDeliveryVehicleManager();
    try {
       DeliveryVehicle vehicle = vehicleManager.getVehicle().get();
       // Handle GetVehicleRequest DeliveryVehicle response.
    } catch (Exception e)  {
       // Handle GetVehicleRequest error.
    }

O DeliveryVehicleManager só pode procurar o DeliveryVehicle do ID do veículo fornecido durante a inicialização da API Delivery Driver.