Pierwsze kroki z pakietem SDK Driver na Androida

Minimalne wymagania systemowe

Na urządzeniu mobilnym musi być zainstalowany Android 6.0 (poziom interfejsu API 23) lub nowszy.

Konfiguracja kompilacji i zależności

Pakiet SDK sterowników w wersji 4.99 i nowszych jest dostępny w repozytorium Google Maven.

Gradle

Dodaj do pliku build.gradle te informacje:

repositories {
    ...
    google()
}

Maven

Dodaj do pliku pom.xml te informacje:

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

Konfiguracja projektu

Aby korzystać z pakietu Driver SDK, Twoja aplikacja musi być kierowana na system minSdkVersion23 lub nowszy. Więcej dowiesz się z artykułu Informacje o wersji.

Aby uruchomić aplikację utworzoną za pomocą pakietu Driver SDK, na urządzeniu z Androidem muszą być zainstalowane Usługi Google Play.

Konfigurowanie projektu programistycznego

Aby skonfigurować projekt programistyczny i uzyskać dla niego klucz interfejsu API w konsoli Google Cloud:

  1. Utwórz nowy projekt w Google Cloud Console lub wybierz istniejący projekt do użycia z pakietem Driver SDK. Zaczekaj kilka minut, aż nowy projekt pojawi się w konsoli Google Cloud.

  2. Aby uruchomić aplikację demonstracyjną, Twój projekt musi mieć dostęp do pakietu Maps SDK na Androida. W konsoli Google Cloud wybierz Interfejsy API i usługi > Biblioteka, a następnie wyszukaj i włącz pakiet SDK Map Google na Androida.

  3. Aby uzyskać klucz interfejsu API dla projektu, wybierz Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz interfejsu API. Więcej informacji o uzyskiwaniu klucza interfejsu API znajdziesz w artykule Uzyskiwanie klucza interfejsu API.

Dodaj do aplikacji pakiet SDK sterownika

Pakiet SDK sterownika jest dostępny w repozytorium Google Maven. Repozytorium zawiera pliki modelu obiektu projektu (.pom) pakietu SDK i dokumenty Javadocs. Aby dodać pakiet SDK sterownika do aplikacji:

  1. Dodaj podaną niżej zależność do konfiguracji Gradle lub Maven, zastępując zmienną VERSION_NUMBER wybraną wersją pakietu SDK sterownika.

    Gradle

    Dodaj do elementu build.gradle:

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

    Maven

    Dodaj do elementu pom.xml:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation.driver</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>[VERSION_NUMBER]</version>
      </dependency>
    </dependencies>
    
  2. Pakiet SDK sterownika wymaga pakietu Navigation SDK. Ta zależność jest skonfigurowana w taki sposób, że jeśli potrzebna jest konkretna wersja pakietu Navigation SDK, należy ją wyraźnie zdefiniować w pliku konfiguracji kompilacji jak poniżej. Pominięcie tego bloku kodu umożliwi projektowi pobieranie najnowszej wersji pakietu Navigation SDK z wersji głównej. Pamiętaj, że połączone działania najnowszych wersji pakietów Driver SDK i Nawigacja SDK zostały poddane rygorystycznym testom przed ich premierą.

    Uporządkuj konfigurację zależności w środowisku programistycznym i utwórz odpowiednie środowiska wersji.

    Gradle

    Dodaj do elementu build.gradle:

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

    Maven

    Dodaj do elementu pom.xml:

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

Dodawanie klucza interfejsu API do aplikacji

Po dodaniu pakietu SDK sterownika do aplikacji dodaj do niej klucz interfejsu API. Musisz użyć klucza interfejsu API projektu uzyskanego podczas konfigurowania projektu.

Ta sekcja zawiera informacje o tym, jak przechowywać klucz interfejsu API, aby aplikacja mogła bezpieczniej się do niego odwoływać. Nie sprawdzaj klucza interfejsu API w systemie kontroli wersji. Powinna znajdować się w pliku local.properties, który znajduje się w katalogu głównym projektu. Więcej informacji o pliku local.properties znajdziesz w artykule o plikach właściwości Gradle.

Aby uprościć to zadanie, użyj wtyczki Gradle obiektów tajnych na Androida. Wykonaj tę procedurę, aby zainstalować wtyczkę do obiektów tajnych Gradle i bezpiecznie przechowywać klucz interfejsu API.

  1. Otwórz plik build.gradle najwyższego poziomu i dodaj poniższy kod do elementu dependencies w sekcji buildscript.

    Zakręcony

    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. Otwórz plik build.gradle na poziomie aplikacji i dodaj poniższy kod do elementu plugins.

    Zakręcony

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

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. Zsynchronizuj projekt z Gradle.

  4. Otwórz local.properties w katalogu na poziomie projektu, a potem dodaj ten kod. Zastąp YOUR_API_KEY swoim kluczem interfejsu API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. W pliku AndroidManifest.xml przejdź do sekcji com.google.android.geo.API_KEY i zaktualizuj atrybut android:value w ten sposób:

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

Ten przykład zawiera pełny plik manifestu przykładowej aplikacji:

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

Uwzględnij w aplikacji wymagane informacje o źródłach

Jeśli w swojej aplikacji używasz pakietu SDK Driver SDK, w sekcji informacji prawnych umieść tekst atrybucji i licencje open source. Informacje o źródłach powinny być dodawane jako niezależne pozycje menu lub jako część menu Informacje.

Informacje o licencjach znajdziesz w pliku „third_party_licenses.txt” w niezarchiwizowanym pliku AAR.

Informacje o tym, jak dodać powiadomienia o otwartym kodzie źródłowym, znajdziesz na stronie https://developers.google.com/android/guides/opensource.

Zależności

Pakiet SDK sterownika używa gRPC do komunikacji z serwerem Fleet Engine. Jeśli nie masz jeszcze zainstalowanego gRPC, konieczne może być zadeklarowanie tych zależności:

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

Bez tych zależności pakiet SDK sterownika może powodować błędy w czasie działania podczas próby komunikacji z serwerem Fleet Engine.

Jeśli do optymalizowania kompilacji używasz ProGuard, może być konieczne dodanie do pliku konfiguracji ProGuard tych wierszy:

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

Minimalny obsługiwany poziom interfejsu API to 23.

Zainicjuj pakiet SDK

Do zainicjowania obiektu DriverContext wymagany jest identyfikator dostawcy (zwykle identyfikator projektu Google Cloud). Więcej informacji o konfigurowaniu projektu Google Cloud znajdziesz w artykule na temat uwierzytelniania i autoryzacji.

Przed skorzystaniem z pakietu Driver SDK musisz go najpierw zainicjować. Aby zainicjować pakiet SDK:

  1. Uzyskaj obiekt Navigator z klasy 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. Utwórz obiekt DriverContext, wypełniając wymagane pola.

    DriverContext driverContext = DriverContext.builder(application)
        .setProviderId(providerId)
        .setVehicleId(vehicleId)
        .setAuthTokenFactory(authTokenFactory)
        .setNavigator(navigator)
        .setRoadSnappedLocationProvider(
            NavigationApi.getRoadSnappedLocationProvider(application))
        .build();
    
  3. Użyj obiektu DriverContext do zainicjowania *DriverApi.

    DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
    
  4. Uzyskaj DeliveryVehicleReporter z obiektu interfejsu API. (DeliveryVehicleReporter rozszerza NavigationVehicleReporter).

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

Uwierzytelniam w: AuthTokenFactory

Gdy pakiet SDK sterownika generuje aktualizacje lokalizacji, musi je wysyłać do serwera Fleet Engine. Aby uwierzytelnić te żądania, pakiet SDK sterowników wywołuje instancję AuthTokenFactory z elementem wywołującym. Fabryka jest odpowiedzialna za generowanie tokenów uwierzytelniania w czasie aktualizacji lokalizacji.

Sposób generowania tokenów zależy od sytuacji każdego dewelopera. Implementacja musi jednak prawdopodobnie:

  • Pobranie tokena uwierzytelniania, prawdopodobnie w formacie JSON, z serwera HTTPS
  • analizowanie i buforowanie tokena
  • odśwież token, gdy straci ważność

Informacje o tokenach oczekiwanych przez serwer Fleet Engine znajdziesz w artykule o tworzeniu tokena internetowego JSON (JWT) na potrzeby autoryzacji.

Oto szkielet implementacji obiektu 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);
    }
  }
}

W tej konkretnej implementacji do pobierania tokena w formacie JSON z serwera uwierzytelniania programisty używa wbudowanego klienta HTTP Java. Token zostaje zapisany do ponownego wykorzystania. Token zostanie pobrany ponownie, jeśli stary token wygaśnie w ciągu 10 minut.

Twoja implementacja może działać inaczej, np. odświeżać tokeny przez wątek w tle.

Wyjątki w tabeli AuthTokenFactory są traktowane jako przejściowe, chyba że występują wielokrotnie. Po kilku próbach pakiet SDK sterownika zakłada, że błąd jest trwały, i przestaje próbować wysyłać aktualizacje.

Raportowanie stanu i błędów w usłudze StatusListener

Pakiet SDK sterownika wykonuje działania w tle, dlatego używaj polecenia StatusListener do aktywowania powiadomień po wystąpieniu określonych zdarzeń, takich jak błędy, ostrzeżenia czy komunikaty debugowania. Błędy mogą mieć charakter przejściowy (np. BACKEND_CONNECTIVITY_ERROR) lub powodować trwałe zatrzymanie aktualizacji lokalizacji (np. VEHICLE_NOT_FOUND, co wskazuje na błąd konfiguracji).

Podajesz opcjonalną implementację StatusListener, taką jak poniżej:

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

Uwagi dotyczące SSL/TLS

Wewnętrznie implementacja pakietu Driver SDK wykorzystuje protokół SSL/TLS do bezpiecznej komunikacji z serwerem Fleet Engine. Wcześniejsze wersje Androida (interfejs API w wersji 23 lub starszej) mogą wymagać poprawki SecurityProvider do komunikacji z serwerem. Więcej informacji o pracy z protokołem SSL na Androidzie znajdziesz w artykule o dostawcy zabezpieczeń GMS. Znajdziesz w nim też przykładowy kod do zastosowania poprawki u dostawcy zabezpieczeń.

Włącz aktualizacje lokalizacji

Jeśli masz już instancję *VehicleReporter, włączenie aktualizacji lokalizacji jest proste:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

Aktualizacje lokalizacji są wysyłane w regularnych odstępach czasu, o ile to możliwe. Każda aktualizacja lokalizacji wskazuje też, że pojazd jest online.

Domyślnie interwał raportowania wynosi 10 sekund. Interwał raportowania możesz zmienić za pomocą reporter.setLocationReportingInterval(long, TimeUnit). Minimalny obsługiwany interwał aktualizacji to 5 sekund. Częstsze aktualizacje mogą powodować wolniejsze przesyłanie żądań i błędy.

Wyłącz aktualizacje lokalizacji

Gdy kierowca zakończy pracę, możesz zatrzymać aktualizowanie lokalizacji, dzwoniąc pod numer DeliveryVehicleReporter.disableLocationTracking.

Przypadki użycia modelu zaufanego

W tej sekcji dowiesz się, jak korzystać z pakietu SDK sterownika do wdrażania typowych przypadków użycia za pomocą modelu zaufanego.

Utwórz pojazd

Możesz utworzyć pojazd za pomocą pakietu Driver SDK.

Zanim utworzysz pojazd, zainicjuj interfejs Delivery Driver API. Identyfikator pojazdu należy utworzyć z identyfikatorem pojazdu i dostawcy użytymi podczas inicjowania pakietu SDK kierowcy. Następnie utwórz pojazd, jak w tym przykładzie:

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

Tworzenie zadania odbioru przesyłki

Zadanie odbioru przesyłki możesz utworzyć w pakiecie SDK sterownika.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Zadanie należy utworzyć przy użyciu identyfikatora dostawcy podanego podczas inicjowania pakietu SDK sterownika. Następnie utwórz zadanie odbioru przesyłki, jak pokazano w poniższym przykładzie. Więcej informacji o identyfikatorach zadań znajdziesz w sekcji Przykłady identyfikatorów zadań.

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

Tworzenie zadania dostawy

Zadanie dostawy przesyłki możesz utworzyć w pakiecie SDK sterownika.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zadanie dostawy zgodnie z poniższym przykładem. Więcej informacji o identyfikatorach zadań znajdziesz w artykule Przykłady identyfikatorów zadań.

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

Zaplanowana niedostępność

Z pakietu SDK kierowcy możesz utworzyć zadanie wskazujące niedostępność (np. w przypadku przerw kierowcy lub uzupełnienia paliwa). Zaplanowane zadanie niedostępności nie może zawierać identyfikatora śledzenia. Opcjonalnie możesz podać lokalizację.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zadanie związane z niedostępnością, jak pokazano w poniższym przykładzie. Więcej informacji o identyfikatorach zadań znajdziesz w artykule Przykłady identyfikatorów zadań.

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

Zaplanowane przystanki

Zadanie zaplanowanego zatrzymania możesz utworzyć w pakiecie SDK sterownika. Zaplanowane zadanie zatrzymania może nie zawierać identyfikatora śledzenia.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zadanie zaplanowanego zatrzymania, jak pokazano w tym przykładzie. Więcej informacji o identyfikatorach zadań znajdziesz w artykule Przykłady identyfikatorów zadań.

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

Zaktualizuj kolejność zadań

Możesz zaktualizować kolejność wykonywania zadań przypisanych do pojazdu z pakietu SDK kierowcy.

Aktualizacja kolejności zadań powoduje też przypisanie do pojazdu zadań, które nie zostały wcześniej przypisane do pojazdu. Zamyka również zadania, które zostały wcześniej przypisane do pojazdu i które nie zostały uwzględnione w zaktualizowanej kolejności. Przypisanie zadania do innego pojazdu, jeśli zostało ono wcześniej przypisane do innego pojazdu, spowoduje wystąpienie błędu. Zanim przypiszesz zadanie do nowego pojazdu, zamknij bieżące zadanie, a następnie utwórz nowe.

Kolejność zadań możesz zmienić w każdej chwili.

Zanim zaktualizujesz kolejność zadań dla pojazdu, sprawdź, czy pojazd i zadania zostały już utworzone we Fleet Engine. Następnie zaktualizuj kolejność zadań dla pojazdu, jak pokazano w tym przykładzie.

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

Może wystąpić wyjątek, który uniemożliwi aktualizację wewnętrznego stanu pakietu SDK sterownika. Jeśli tak się stanie, rozwiąż problem, a następnie wywołaj ponownie setVehicleStops, aż połączenie się powiedzie.

Możliwe problemy to między innymi:

  • Podane wartości VehicleStops są niezgodne z prawidłowym wzorcem. Tylko pierwszy pojazd może mieć wartość VehicleStopStates: NEW, ENROUTE lub ARRIVED. W przypadku postoju w przypadku bieżącego postoju musi on mieć wartość NEW VehicleStopState.

  • Zadania nie istnieją lub należą do innego pojazdu.

  • Pojazd nie istnieje.

Pojazd jest w drodze do następnego przystanku

Usługa Fleet Engine musi być powiadamiana, gdy pojazd wychodzi ze postoju i gdy rozpoczyna nawigację. Możesz powiadomić Fleet Engine za pomocą pakietu SDK sterownika.

Zanim powiadomisz Fleet Engine o tym, że pojazd wyszedł ze postoju, sprawdź, czy pojazd został utworzony i ustawiony. Następnie powiadom Fleet Engine o odjazdu pojazdu, jak pokazano w tym przykładzie.

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

Może wystąpić wyjątek, który uniemożliwi aktualizację wewnętrznego stanu pakietu SDK sterownika. Jeśli tak się stanie, rozwiąż problem, a następnie wywołaj ponownie metodę enrouteToNextStop, aż się uda.

Możliwe problemy to między innymi:

  • Brak pozostałych elementów VehicleStops w pakiecie Driver SDK.

Pojazd na przystanku

Usługa Fleet Engine musi otrzymać powiadomienie, gdy pojazd się zatrzyma. Możesz powiadamiać usługę Fleet Engine za pomocą pakietu SDK sterownika.

Zanim powiadomisz Fleet Engine o zatrzymaniu pojazdu, upewnij się, że ustawiono postoje. Następnie powiadom Fleet Engine o przybyciu pojazdu na postoju, jak pokazano w tym przykładzie.

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

Wyjątek może uniemożliwić aktualizację stanu wewnętrznego pakietu SDK sterownika. Jeśli tak się stanie, rozwiąż problem, a następnie wywołaj jeszcze raz arrivedAtStop, aż się uda.

Możliwe problemy to m.in.:

  • Brak pozostałych elementów VehicleStops w pakiecie Driver SDK.

Pojazd kończy postój

Musisz powiadomić Fleet Engine o zatrzymaniu pojazdu. To powiadomienie powoduje, że wszystkie zadania powiązane z przystankiem zmienią się w stan ZAMKNIĘTE. Możesz powiadamiać usługę Fleet Engine za pomocą pakietu SDK sterownika.

Powiadom Fleet Engine o zakończeniu operacji MachineStop, jak pokazano w poniższym przykładzie.

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

Wyjątek może uniemożliwić aktualizację stanu wewnętrznego pakietu SDK sterownika. Jeśli tak się stanie, rozwiąż problem, a następnie wywołaj jeszcze raz completedStop, aż się uda.

Możliwe problemy to między innymi:

  • Brak pozostałych elementów VehicleStops w pakiecie Driver SDK.

Zamykanie zadania

Aby zamknąć zadanie przypisane do pojazdu, możesz powiadomić Fleet Engine o zakończeniu postoju, na którym odbywa się zadanie, lub usunąć go z listy postojów. Aby to zrobić, możesz ustawić listę pozostałych przystanków tak samo jak podczas aktualizowania kolejności zadań dla pojazdu.

Jeśli do zadania nie przypisano jeszcze pojazdu i trzeba je zamknąć, zmień to zadanie na ZAMKNIĘTE. Nie możesz jednak ponownie otworzyć zadania ZAMKNIĘTE.

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia. Sygnalizuje to, że zadanie nie jest już uważane za wykonywane. W przypadku śledzenia przesyłki ważne jest wskazanie rzeczywistego wyniku zadania, aby można było zobaczyć wynik dostawy.

Aby można było je zamknąć za pomocą pakietu SDK kierowcy, trzeba je przypisać do pojazdu. Aby zamknąć zadanie przypisane do pojazdu, powiadom Fleet Engine o tym, że pojazd zakończył postój, na którym to zadanie jest wykonywane.

Możesz też zaktualizować kolejność zadań w pojeździe, do którego zadanie jest przypisane, a następnie usunąć zadanie z listy przystanków.

Ustaw wynik działania i lokalizację wyników

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia. Sygnalizuje to, że zadanie nie jest już uważane za wykonywane. W przypadku śledzenia przesyłek ważne jest wskazanie rzeczywistego wyniku zadania, aby można było zobaczyć wynik dostawy i rozliczenia za usługi. Po ustawieniu nie możesz zmienić wyniku zadania. Możesz jednak zmienić czas i lokalizację wyniku zadania.

Zadania, które mają stan ZAMKNIĘTE, mogą mieć wynik SUCCEEDED lub FAILED. Fleet Engine nalicza opłaty tylko za zadania dostarczania ze stanem SUCCEEDED.

Zaznaczając wynik zadania, Fleet Engine automatycznie wypełnia lokalizację wyniku zadania ostatnią znaną lokalizacją pojazdu. Możesz zastąpić to działanie.

Z przykładu poniżej dowiesz się, jak za pomocą pakietu SDK sterownika ustawić wynik zadania i sygnaturę czasową. Nie możesz ustawić lokalizacji wyniku zadania za pomocą pakietu SDK sterownika.

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

Wyszukiwanie pojazdu

Pojazd możesz wyszukać w pakiecie SDK kierowcy. Zanim wyszukasz pojazd, zainicjuj interfejs Delivery Driver API. Możesz wyszukać pojazd, tak jak w poniższym przykładzie.

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

DeliveryVehicleManager może wyszukać w DeliveryVehicle tylko identyfikator pojazdu, który został podany podczas inicjowania interfejsu Delivery Driver API.