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, seu 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 seu projeto de desenvolvimento e gerar uma chave de API para ele no Console do Google Cloud:

  1. Crie um novo projeto do Console do Google Cloud ou selecione um projeto atual 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 Gerar uma chave de API.

Adicionar o SDK do Driver ao app

O SDK do Driver está disponível no repositório Maven do Google. O repositório inclui os arquivos .pom (Project Object Model) do SDK e Javadocs. Para adicionar o SDK do Driver ao app:

  1. Adicione a dependência abaixo à configuração do Gradle ou do Maven, substituindo o marcador VERSION_NUMBER da 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 do Driver depende do SDK do Navigation. Essa dependência é configurada de modo que, se uma versão específica do SDK do Navigation for necessária, ela precisa ser explicitamente definida no arquivo de configuração do build, como mostrado abaixo. 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 principal. Os comportamentos combinados das versões mais recentes do SDK do Driver e do SDK do Navigation foram submetidos a testes rigorosos antes do lançamento.

    Organize a configuração de dependência dos ambientes de desenvolvimento e lançamento.

    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, adicione a chave de API a ele. É necessário usar a chave de API do projeto que você recebeu ao configurar seu projeto de desenvolvimento.

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

Para otimizar essa tarefa, use o plug-in Secrets Gradle para Android (link em inglês). Siga este procedimento para instalar o plug-in Secrets Gradle e armazenar com segurança sua chave de API.

  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 seguinte código. 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 app

Se você usa o SDK do Driver no app, precisa 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 trouxe o gRPC, talvez seja 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 suas versões, 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 de API com suporte é 23.

Inicializar o SDK

Um ID do 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, é necessário inicializar o SDK do Navigation. Para iniciar o SDK:

  1. Consiga 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 maneira exata como os tokens são gerados é específica para cada situação de desenvolvedor. No entanto, a implementação provavelmente precisará:

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

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

Confira o esqueleto de implementação 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);
    }
  }
}

Essa 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 coisas de forma diferente, como usar uma linha de execução em segundo plano para atualizar tokens.

Exceções em AuthTokenFactory são tratadas como temporárias, a menos que aconteçam repetidamente. Depois de 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 de natureza temporária (como BACKEND_CONNECTIVITY_ERROR) ou podem fazer com que as atualizações de local sejam interrompidas permanentemente (como VEHICLE_NOT_FOUND, indicando um erro de configuração).

Você fornece uma implementação de 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 mais antigas do Android (a 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 SSL no Android, consulte Provedor de GMS de segurança. O artigo também contém exemplos de código para aplicar patches ao provedor de segurança.

Ativar atualizações de localização

Quando você tiver uma instância de *VehicleReporter, será fácil ativar as atualizações de localização:

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 mudar o intervalo do relatório com reporter.setLocationReportingInterval(long, TimeUnit). O intervalo de atualização mínimo com suporte é de cinco segundos. Atualizações mais frequentes podem resultar em solicitações e erros mais lentos.

Desativar atualizações de localização

Quando o turno do motorista for concluído, 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 usando o SDK do Driver.

Antes de criar um veículo, inicialize a API Delivery Driver. O ID do veículo precisa ser criado com o veículo e o ID do provedor usados durante a inicialização do SDK do motorista. 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 frete

Você pode criar uma tarefa de retirada de remessas no SDK do Driver.

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 da remessa, 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)
   .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 de remessa

É possível criar uma tarefa de entrega de remessa no SDK do Driver.

Antes de criar uma tarefa, inicialize a API Delivery Driver. Em seguida, crie a tarefa de entrega da 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 indique indisponibilidade (por exemplo, para pausas do motorista ou reabastecimento de veículos) no SDK do Driver. Uma tarefa de indisponibilidade programada não pode incluir um ID de acompanhamento. Também é possível informar um local.

Antes de criar uma tarefa, inicialize a API Delivery Driver. Em seguida, crie a tarefa de indisponibilidade, 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)
   .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. Uma tarefa de parada programada pode não incluir 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 pelo SDK do motorista.

A atualização da ordem de tarefas também atribui tarefas a um veículo, caso elas não tenham sido atribuídas a um veículo. Ele também fecha tarefas que foram atribuídas a um veículo e foram deixadas de fora da ordem atualizada. Quando uma tarefa é atribuída a um veículo diferente, caso ela tenha sido atribuída a outro veículo, isso gera um erro. Antes de atribuir uma tarefa ao novo veículo, feche a tarefa existente 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 a seguir.

    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 bem-sucedida.

Os possíveis problemas podem incluir:

  • Os VehicleStops especificados não seguem um padrão válido. Apenas a primeira VehicleStop pode estar em qualquer um dos VehicleStopStates: NEW, ENROUTE ou ARRIVED. As paradas de veículos depois da parada atual precisam estar no estado NEW 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 Fleet Engine precisa ser notificado quando um veículo sai de uma parada e quando inicia a navegação. Você pode notificar o Fleet Engine pelo SDK do driver.

Antes de notificar o Fleet Engine de que um veículo saiu 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, como 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 pode impedir uma atualização do 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 definido no SDK do Driver.

O veículo chega a uma parada

O Fleet Engine precisa ser notificado quando um veículo chega a uma parada. Você pode notificar o Fleet Engine pelo SDK do Driver.

Antes de notificar o Fleet Engine de 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 pode impedir uma atualização do estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame arrivedAtStop novamente até que tenha êxito.

Os possíveis problemas podem incluir:

  • Nenhum VehicleStops restante definido no SDK do Driver.

O veículo conclui uma parada

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

Notifique a Fleet Engine 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 pode impedir uma atualização do estado interno do SDK do driver. Se isso acontecer, resolva o problema e chame completedStop novamente até que tenha êxito.

Os possíveis problemas podem incluir:

  • Nenhum VehicleStops restante definido no SDK do Driver.

Fechar uma tarefa

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 ocorre ou remova-o da lista de paradas de veículos. Para isso, você pode definir a lista de paradas de veículos restantes da mesma maneira 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 precisar ser fechada, atualize a tarefa para o estado CLOSED. No entanto, não é possível reabrir uma tarefa CLOSED.

Encerrar uma tarefa não indica sucesso ou falha. Ele indica que a tarefa não é mais considerada em andamento. No rastreamento de remessas, é 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 poder usar o SDK do motorista e fechar a tarefa. Para fechar uma tarefa atribuída a um veículo, notifique o Frleet Engine que o veículo concluiu a parada em que a tarefa ocorre.

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

Definir o resultado da tarefa e o local dos resultados

Fechar uma tarefa não indica sucesso ou falha. Ele indica que a tarefa não é mais considerada em andamento. No rastreamento de remessas, é importante indicar o resultado real de uma tarefa para que um resultado de entrega possa ser mostrado e que os serviços sejam cobrados adequadamente. Uma vez definido, não é possível mudar o resultado da tarefa. Mas é possível modificar o horário e o local do resultado da tarefa depois de defini-los.

As tarefas no estado CLOSED podem ter os resultados definidos como SUCCEEDED ou FAILED. O Fleet Engine cobra apenas as tarefas de entrega com estado SUCCEEDED.

Ao marcar o resultado de uma tarefa, o Fleet Engine preenche automaticamente o local do resultado com a última localização conhecida do veículo. É possível modificar esse comportamento.

O exemplo abaixo mostra como usar o SDK do Driver para definir um resultado de tarefa e um carimbo de data/hora. Não é possível definir o local do 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

Você pode procurar um veículo no SDK do Driver. Antes de procurar um veículo, inicialize a API Delivery Driver. Em seguida, pesquise o veículo conforme mostrado no exemplo a seguir.

    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.