Primeiros passos com o SDK do driver para Android

Você pode usar o SDK do Driver para oferecer navegação e rastreamento aprimorados ao seu aplicativo Trip and Order Progress. O SDK do Driver oferece atualizações de localização de veículos e tarefas no Fleet Engine da solução de viagens e entregas sob demanda.

O SDK do Driver mantém os serviços do Fleet Engine e seus serviços personalizados cientes da localização e do estado do veículo. Por exemplo, o veículo pode ser ONLINE. ou OFFLINE, e a localização do veículo muda conforme a viagem progride.

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 minSdkVersion 23 ou mais recente.

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

Configurar seu projeto de desenvolvimento

Como configurar seu projeto de desenvolvimento e gerar 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 atual para usar com o SDK do Driver. Aguarde alguns minutos até o novo projeto fica 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 > Library, pesquise e ative o SDK do Maps para Android

  3. Receba uma chave de API para o projeto selecionando APIs e Serviços > Credenciais > Criar credenciais > Chave de API. Para mais informações sobre como acessar uma chave de API, consulte Gere uma chave de API.

Adicionar o SDK do Driver ao app

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

  1. Adicione a seguinte dependência à sua configuração do Gradle ou Maven, substituindo " O marcador VERSION_NUMBER para a versão desejada 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</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 uma de modo que, se uma versão específica do SDK do Navigation for necessária, ela será explicitamente definido no arquivo de configuração do build, da seguinte maneira: a omissão do bloco de código mencionado permitirá que o projeto sempre faça o download a versão mais recente do SDK do Navigation na versão de lançamento principal; Observe que os comportamentos combinados das versões mais recentes do SDK do Driver e O SDK do Navigation foi submetido a testes rigorosos antes do lançamento.

    Organizar a configuração de dependências dos aplicativos de desenvolvimento e versão de acordo com os ambientes.

    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. Você precisa usar a chave de API do projeto que você recebeu quando configure seu projeto de desenvolvimento.

Esta seção descreve como armazenar sua chave de API para que ela seja mais segura referenciadas pelo seu app. Não inclua a chave de API na sua versão de controle de acesso. Ele será armazenado no arquivo local.properties, que é localizado no diretório raiz do seu projeto. Para mais informações sobre o local.properties, consulte Arquivos de propriedades do Gradle.

Para otimizar essa tarefa, use o Plug-in Secrets Gradle para Android (em inglês).

Para instalar o plug-in e armazenar sua chave de API, siga estas instruções:

  1. Abra seu 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 plugins.

    Groovy

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

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Se você usa o Android Studio, sincronizar seu projeto com o Gradle.

  4. Abra o local.properties no diretório do nível do projeto e adicione o código a seguir. 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 desta forma:

    <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, é necessário incluir texto de atribuição e licenças de código aberto como parte dos avisos legais do seu app nesta seção. É melhor incluir as atribuições como um item de menu independente ou como no item de menu Sobre.

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

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

Dependências

Se você usa o ProGuard para otimizar suas compilações, pode ser necessário adicionar as seguintes linhas ao seu ProGuard de configuração do Terraform:

-dontwarn com.google.**
-dontwarn okio.**

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

Initializing the 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 projeto do Google Cloud, consulte Autenticação e autorização.

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

  1. Consiga um objeto Navigator do NavigationApi.

    Java

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

    Kotlin

    NavigationApi.getNavigator(
      this, // Activity
      object : NavigatorListener() {
        override fun onNavigatorReady(navigator: Navigator) {
          // Keep a reference to the Navigator (used to configure and start nav)
          this@myActivity.navigator = navigator
        }
      },
    )
    
  2. Crie um objeto DriverContext, preenchendo os campos obrigatórios.

    Java

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    

    Kotlin

    val 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.

    Java

    RidesharingDriverApi ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext);
    

    Kotlin

    val ridesharingDriverApi = RidesharingDriverApi.createInstance(driverContext)
    
  4. Consiga o RidesharingVehicleReporter do objeto da API. (*VehicleReporter estende NavigationVehicleReporter.)

    Java

    RidesharingVehicleReporter vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter();
    

    Kotlin

    val vehicleReporter = ridesharingDriverApi.getRidesharingVehicleReporter()
    

Como autenticar com AuthTokenFactory

Quando o SDK do Driver gera atualizações de localização, ele precisa enviar essas atualizações para no servidor do Fleet Engine. Para autenticar essas solicitações, o O SDK do Driver vai chamar o autor da chamada instância de AuthTokenFactory. A fábrica é responsável por gerar tokens de autenticação no local e a hora da atualização.

A maneira exata como os tokens são gerados será específico para a situação de cada 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

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

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

Java

class JsonAuthTokenFactory implements AuthTokenFactory {
  private String token;  // 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(authTokenContext.getVehicleId());
    }
    return token;
  }

  private void fetchNewToken(String vehicleId) {
    String url =
        new Uri.Builder()
            .scheme("https")
            .authority("yourauthserver.example")
            .appendPath("token")
            .appendQueryParameter("vehicleId", vehicleId)
            .build()
            .toString();

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
      token = obj.get("Token").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);
    }
  }
}

Kotlin

class JsonAuthTokenFactory : AuthTokenFactory() {

  private var token: String = ""
  private var expiryTimeMs: Long = 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 fun getToken(context: AuthTokenContext): String {
    if (System.currentTimeMillis() > expiryTimeMs) {
      // The token has expired, go get a new one.
      fetchNewToken(authTokenContext.getVehicleId())
    }
     return token
  }

  fun fetchNewToken(vehicleId: String) {
    val url =
      Uri.Builder()
        .scheme("https")
        .authority("yourauthserver.example")
        .appendPath("token")
        .appendQueryParameter("vehicleId", vehicleId)
        .build()
        .toString()

    try {
      val reader = InputStreamReader(URL(url).openStream())

      reader.use {
        val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()

        token = obj.get("ServiceToken").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 (e: IOException) {
      // 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 RuntimeException("Could not get auth token", e)
    }
  }
}

Essa implementação específica usa o cliente HTTP Java integrado para buscar uma token em formato JSON do servidor de autenticação do desenvolvedor. O token é salvas para reutilização. O token será buscado novamente se o token antigo estiver dentro de 10 minutos. do tempo de validade.

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

As exceções em AuthTokenFactory serão tratadas como temporárias, a menos que aconteçam repetidamente. Depois de algumas tentativas, o SDK do Driver vai assumir que o é permanente e interromperá a tentativa de enviar atualizações.

Status e relatórios de erros com StatusListener

Como o SDK do Driver realiza ações segundo plano, use StatusListener para acionar notificações quando determinados como erros, avisos ou mensagens de depuração. Os erros podem ser temporária por natureza (como BACKEND_CONNECTIVITY_ERROR), ou podem fazer com que as atualizações de localização sejam interrompidas permanentemente (como VEHICLE_NOT_FOUND, indicando um erro de configuração).

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

Java

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.
  }
}

Kotlin

class MyStatusListener : StatusListener() {
  /** Called when background status is updated, during actions such as location reporting. */
  override fun updateStatus(statusLevel: StatusLevel, statusCode: StatusCode, statusMsg: String) {
    // 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 comunicação segura com o servidor do Fleet Engine. Versões mais antigas do Android (versões 19 ou anterior) pode exigir que um patch SecurityProvider possa se comunicar com o servidor. Vai aparecer este artigo para mais informações sobre como trabalhar com SSL no Android. O artigo também contém exemplos de código para aplicar patches ao provedor de segurança.

Ativando atualizações de localização

Quando você tiver uma instância do *VehicleReporter, será necessário ativar as atualizações de localização. direta:

Java

RidesharingVehicleReporter reporter = ...;

reporter.enableLocationTracking();

Kotlin

val reporter = ...

reporter.enableLocationTracking()

As atualizações de localização são enviadas em intervalos regulares quando o estado do veículo é ONLINE: Observe que chamar reporter.enableLocationTracking() não define automaticamente o estado do veículo como ONLINE. Você deve defina o estado do veículo explicitamente.

Por padrão, o intervalo do relatório é de 10 segundos. O intervalo do relatório pode será alterado com reporter.setLocationReportingInterval(long, TimeUnit). A o intervalo mínimo de atualização permitido é de cinco segundos. Atualizações mais frequentes podem resultam em solicitações e erros mais lentos.

Desativar atualizações de localização

Quando o turno do motorista termina, as atualizações de localização podem ser interrompidas e o veículo marcado como off-line ligando para DeliveryVehicleReporter.disableLocationTracking ou RidesharingVehicleReporter.disableLocationTracking.

Essa ligação fará com que uma última atualização seja agendada para entrega imediata, indicando que o veículo está off-line. Essa atualização não conterá as configurações o local.

Definir o estado do veículo

Quando as atualizações de localização estão ativadas, definir o estado do veículo como ONLINE vai disponibilizar o veículo para consultas de SearchVehicles; da mesma forma, marcar uma OFFLINE vai marcar o veículo como indisponível.

Você tem a opção de definir o estado do veículo no lado do servidor (consulte Atualizar um veículo), ou diretamente no SDK do Driver:

Java

RidesharingVehicleReporter reporter = ...;

reporter.enableLocationTracking();
reporter.setVehicleState(VehicleState.ONLINE);

Kotlin

val reporter = ...

reporter.enableLocationTracking()
reporter.setVehicleState(VehicleState.ONLINE)

Quando as atualizações de local estiverem ativadas, uma chamada para setVehicleState será propagada a próxima atualização de local.

Marcar um veículo como ONLINE quando o rastreamento de localização não estiver ativado em um IllegalStateException. Um veículo pode ser marcado como OFFLINE quando o monitoramento de local ainda não está ativado ou desativado explicitamente. Isso resultará em em uma atualização imediata. Uma chamada para RidesharingVehicleReporter.disableLocationTracking() vai Defina o estado do veículo como OFFLINE.

Observe que setVehicleState retorna imediatamente e as atualizações são feitas no conversa de atualização de local. Semelhante ao tratamento de erros de atualizações de locais, os erros atualizar o estado do veículo são propagadas usando o método StatusListener definido no DriverContext.