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 lub nowszej 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 można było używać pakietu Driver SDK, aplikacja musi być kierowana na system minSdkVersion w wersji 23 lub nowszej. Więcej informacji znajdziesz w informacjach o wersji.

Aby uruchomić aplikację stworzoną przy użyciu 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 konsoli Google Cloud 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ę w wersji demonstracyjnej, 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 Maps SDK na Androida.

  3. Aby uzyskać klucz interfejsu API dla projektu, kliknij Interfejsy API i usługi > Dane logowania > Utwórz dane logowania > Klucz interfejsu API. Jeśli chcesz dowiedzieć się, jak uzyskać klucz interfejsu API, przeczytaj, jak uzyskać klucz interfejsu API.

Dodaj pakiet Driver SDK do aplikacji

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

  1. Dodaj poniższą zależność do konfiguracji Gradle lub Maven, zastępując zmienną VERSION_NUMBER dla wybranej wersji pakietu Driver SDK.

    Gradle

    Dodaj do build.gradle:

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

    Maven

    Dodaj do 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 Driver SDK opiera się na pakiecie Navigation SDK. Zależność ta jest skonfigurowana w taki sposób, że jeśli potrzebna jest konkretna wersja pakietu Navigation SDK, trzeba ją wyraźnie zdefiniować w pliku konfiguracji kompilacji, tak jak w przykładzie poniżej. Pominięcie wspomnianego bloku kodu umożliwi projektowi zawsze pobieranie najnowszej wersji pakietu Navigation SDK w ramach wersji głównej. Pamiętaj, że połączone działania najnowszych wersji pakietów Driver SDK i Navigation SDK zostały poddane rygorystycznym testom przed ich opublikowaniem.

    Uporządkuj konfigurację zależności w programie i odpowiednio opublikuj środowiska.

    Gradle

    Dodaj do build.gradle:

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

    Maven

    Dodaj do 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 do aplikacji pakietu Driver SDK dodaj do niej klucz interfejsu API. Musisz użyć klucza interfejsu API projektu uzyskanego podczas konfigurowania projektu programistycznego.

W tej sekcji dowiesz się, jak przechowywać klucz interfejsu API, aby aplikacja mogła lepiej się do niego odwoływać. Nie należy sprawdzać klucza interfejsu API w systemie kontroli wersji. Powinien on być przechowywany 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 usprawnić to zadanie, użyj wtyczki Gradle obiektów tajnych dla Androida. Wykonaj tę procedurę, aby zainstalować wtyczkę Gradle obiektów tajnych i bezpiecznie przechowywać klucz interfejsu API.

  1. Otwórz plik build.gradle poziomu głównego i dodaj poniższy kod do elementu dependencies w 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 następnie dodaj ten kod. Pamiętaj, aby zastąpić YOUR_API_KEY kluczem interfejsu API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. W pliku AndroidManifest.xml przejdź do miejsca 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>

Umieść w aplikacji wymagane informacje o źródłach

Jeśli w swojej aplikacji używasz pakietu Driver SDK, w sekcji Informacje prawne musisz uwzględnić tekst atrybucji i licencje open source. Informacje o źródłach najlepiej dodawać jako niezależną pozycję menu lub jako część pozycji Informacje.

Informacje o licencjach znajdziesz w pliku „third_party_licenses.txt” w przywróconym pliku AAR.

Informacje o tym, jak dołączać powiadomienia o oprogramowaniu open source, znajdziesz na https://developers.google.com/android/guides/opensource.

Zależności

Pakiet Driver SDK używa gRPC do komunikacji z serwerem Fleet Engine. Jeśli nie stosujesz jeszcze 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 podczas próby komunikacji z serwerem Fleet Engine w pakiecie Driver SDK mogą występować błędy.

Jeśli do optymalizacji kompilacji używasz ProGuard, być może trzeba będzie dodać te wiersze do pliku konfiguracji ProGuard:

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

Minimalny obsługiwany poziom interfejsu API to 23.

Inicjowanie pakietu 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 Uwierzytelnianie i autoryzacja.

Zanim zaczniesz używać pakietu Driver SDK, musisz najpierw zainicjować pakiet SDK Navigation. Aby zainicjować pakiet SDK:

  1. Uzyskaj obiekt Navigator z 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. Zainicjuj obiekt *DriverApi za pomocą obiektu DriverContext.

    DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
    
  4. Uzyskaj DeliveryVehicleReporter z obiektu interfejsu API. (DeliveryVehicleReporter przedłuża się o NavigationVehicleReporter).

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

Uwierzytelnianie w sieci AuthTokenFactory

Gdy pakiet Driver SDK generuje aktualizacje lokalizacji, musi je wysłać do serwera Fleet Engine. Aby uwierzytelnić te żądania, pakiet Driver SDK wywołuje udostępnianą przez funkcję wywołującą instancję AuthTokenFactory. Fabryka odpowiada za generowanie tokenów uwierzytelniania w momencie aktualizacji lokalizacji.

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

  • pobranie tokena uwierzytelniania, prawdopodobnie w formacie JSON, z serwera HTTPS
  • przeanalizować token i przechowywać go w pamięci podręcznej
  • odświeżaj token po jego wygaśnięciu

Szczegółowe informacje o tokenach oczekiwanych przez serwer Fleet Engine znajdziesz w artykule Tworzenie tokena internetowego JSON (JWT) na potrzeby autoryzacji.

Oto szkieletowa implementacja elementu 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);
    }
  }
}

Ta konkretna implementacja korzysta z wbudowanego klienta HTTP Java, by pobrać token w formacie JSON z serwera uwierzytelniania dewelopera. Token zaoszczędzisz do ponownego wykorzystania. Jeśli stary token zostanie pobrany w ciągu 10 minut od wygaśnięcia, token zostanie pobrany ponownie.

Implementacja może działać inaczej, np. odświeżać tokeny z użyciem wątku działającego w tle.

Wyjątki w polu AuthTokenFactory są traktowane jako przejściowe, chyba że wystąpią wielokrotnie. Po kilku próbach pakiet Driver SDK zakłada, że błąd jest nieodwracalny i przestaje próbować wysyłać aktualizacje.

Raportowanie stanu i błędów za pomocą usługi StatusListener

Ponieważ pakiet Driver SDK wykonuje działania w tle, używaj zasady StatusListener do aktywowania powiadomień, gdy wystąpią określone zdarzenia, takie jak błędy, ostrzeżenia lub komunikaty debugowania. Błędy mogą być przejściowe (np. BACKEND_CONNECTIVITY_ERROR) lub mogą spowodować trwałe zatrzymanie aktualizacji lokalizacji (np. VEHICLE_NOT_FOUND, co oznacza błąd konfiguracji).

Udostępniasz opcjonalną implementację StatusListener:

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 na temat protokołu SSL/TLS

Wewnętrznie implementacja pakietu Driver SDK używa SSL/TLS do bezpiecznej komunikacji z serwerem Fleet Engine. We wcześniejszych wersjach Androida (interfejs API w wersji 23 lub starszej) do komunikacji z serwerem może być wymagana poprawka SecurityProvider. Więcej informacji o pracy z protokołem SSL na Androidzie znajdziesz na stronie dostawcy zabezpieczeń GMS. Artykuł zawiera też przykładowy kod służący do instalowania poprawek u dostawcy zabezpieczeń.

Włącz aktualizacje lokalizacji

Gdy masz instancję *VehicleReporter, włączenie aktualizacji lokalizacji jest proste:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

Aktualizacje lokalizacji są wysyłane w miarę możliwości w regularnych odstępach czasu. Każda aktualizacja lokalizacji wskazuje też, że pojazd jest online.

Domyślny interwał raportowania wynosi 10 sekund. Częstotliwość raportowania możesz zmienić za pomocą funkcji reporter.setLocationReportingInterval(long, TimeUnit). Minimalny obsługiwany odstęp czasu aktualizacji to 5 sekund. Częstsze aktualizacje mogą powodować wolniejsze przesyłanie żądań i błędów.

Wyłącz aktualizacje lokalizacji

Po zakończeniu zmiany kierowcy możesz zatrzymać aktualizowanie lokalizacji, dzwoniąc pod numer DeliveryVehicleReporter.disableLocationTracking.

Przypadki użycia modelu zaufanego

W tej sekcji dowiesz się, jak używać pakietu Driver SDK do implementacji typowych przypadków użycia zaufanego modelu.

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ć za pomocą pojazdu i identyfikatora dostawcy używanego podczas inicjowania pakietu SDK sterownika 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 dostawy możesz utworzyć za pomocą pakietu Driver SDK.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Zadanie należy utworzyć przy użyciu identyfikatora dostawcy określonego podczas inicjowania pakietu Driver SDK. Następnie utwórz zadanie odbioru przesyłki zgodnie z poniższym przykładem. Informacje 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_PICKUP)
   .build();

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

Tworzenie zadania dostawy

Zadanie dostawy możesz utworzyć za pomocą pakietu Driver SDK.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zadanie dostawy, jak pokazano w przykładzie poniżej. Informacje o identyfikatorach zadań znajdziesz w przykładach 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ść

Za pomocą pakietu Driver SDK możesz utworzyć zadanie wskazujące na niedostępność (np. związane z przerwami kierowcy lub uzupełnianiem paliwa). Zaplanowane zadanie dotyczące niedostępności nie może zawierać identyfikatora śledzenia. Możesz opcjonalnie podać lokalizację.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zadanie dotyczące niedostępności zgodnie z poniższym przykładem. Informacje o identyfikatorach zadań znajdziesz w przykładach 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

Zaplanowane zadanie zatrzymania możesz utworzyć za pomocą pakietu Driver SDK. Zaplanowane zadanie zatrzymania może nie zawierać identyfikatora śledzenia.

Zanim utworzysz zadanie, zainicjuj interfejs Delivery Driver API. Następnie utwórz zaplanowane zadanie zatrzymania zgodnie z poniższym przykładem. Informacje o identyfikatorach zadań znajdziesz w przykładach 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ń

Za pomocą pakietu Driver SDK możesz zaktualizować kolejność wykonywania zadań przypisanych do pojazdu.

Zaktualizowanie kolejności zadań powoduje też przypisanie zadań do pojazdu, jeśli nie zostały do niego wcześniej przypisane. Zamyka to również zadania, które zostały wcześniej przypisane do pojazdu i nie zostały uwzględnione w zaktualizowanej kolejności. Przypisanie zadania do innego pojazdu, jeśli zostało wcześniej przypisane do innego pojazdu, powoduje błąd. Zanim przypiszesz zadanie do nowego pojazdu, zamknij dotychczasowe zadanie i utwórz nowe.

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

Zanim zaktualizujesz kolejność zadań dla pojazdu, sprawdź, czy ten pojazd i zadania zostały już utworzone we Fleet Engine. Następnie zmień kolejność zadań w pojeździe, jak 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żliwia aktualizację stanu wewnętrznego pakietu Driver SDK. Jeśli tak się stanie, rozwiąż problem, a następnie zadzwoń pod numer setVehicleStops, dopóki połączenie się nie powiedzie.

Możliwe problemy:

  • Określone wartości VehicleStops nie są zgodne z prawidłowym wzorcem. Tylko pierwszy VehicleStop może być dowolnym z stanów VehicleStopState: NOWY, W TRAKCIE lub PRZYBYŁ. Zatrzymanie pojazdu po obecnym przystanku musi mieć stan NEW VehicleStopState.

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

  • Pojazd nie istnieje.

Pojazd jest w drodze do następnego przystanku

Należy powiadamiać Fleet Engine, gdy pojazd wyruszy z przystanku i kiedy rozpocznie nawigację. Możesz powiadomić Fleet Engine za pomocą pakietu Driver SDK.

Zanim powiadomisz Fleet Engine, że pojazd wyruszył z przystanku, upewnij się, że utworzono i ustawiono przystanki dla pojazdu. Następnie powiadom Fleet Engine o odjazdu pojazdu, jak pokazano w przykładzie poniżej.

    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 może uniemożliwić aktualizację stanu wewnętrznego pakietu Driver SDK. Jeśli tak się stanie, rozwiąż problem, a następnie wywołuj metodę enrouteToNextStop ponownie, aż wszystko się uda.

Możliwe problemy:

  • W pakiecie SDK Driver SDK nie ma ustawionych żadnych elementów VehicleStops.

Pojazd zbliża się do przystanku

Musisz powiadamiać Fleet Engine, gdy pojazd znajdzie się na przystanku. Możesz powiadamiać Fleet Engine za pomocą pakietu Driver SDK.

Zanim powiadomisz Fleet Engine o zatrzymaniu pojazdu, upewnij się, że jest ono ustawione. Następnie powiadamiaj Fleet Engine o dotarciu pojazdu na przystanek, jak pokazano w przykładzie poniżej.

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

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

Możliwe problemy:

  • W pakiecie SDK Driver SDK nie ma ustawionych żadnych elementów VehicleStops.

Pojazd zatrzymuje się

Musisz powiadomić Fleet Engine o zakończeniu zatrzymania pojazdu. To powiadomienie powoduje, że wszystkie zadania powiązane z przystankiem zostają ustawione jako ZAMKNIĘTE. Możesz powiadamiać Fleet Engine za pomocą pakietu Driver SDK.

Powiadom usługę Fleet Engine, że pojazd zakończył działanie VehicleStop, 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.
    }

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

Możliwe problemy:

  • W pakiecie SDK Driver SDK nie ma ustawionych żadnych elementów VehicleStops.

Zamykanie zadania

Aby zamknąć zadanie przypisane do pojazdu, powiadom Fleet Engine, że pojazd ukończył przystanek, na którym odbywa się to zadanie, lub usuń go z listy postojów. Aby to zrobić, możesz ustawić listę pozostałych przystanków pojazdu tak samo jak podczas aktualizowania kolejności zadań w przypadku danego pojazdu.

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

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia. Oznacza ono, że zadanie nie jest już uważane za trwające. W przypadku śledzenia przesyłki ważne jest, aby wskazać rzeczywisty wynik zadania, aby można było poznać efekt dostarczenia przesyłki.

Aby można było zamknąć zadanie za pomocą pakietu Driver SDK, należy przypisać zadanie do pojazdu. Aby zamknąć zadanie przypisane do pojazdu, powiadom usługę Fleet Engine o tym, że pojazd zakończył zatrzymanie, na którym to zadanie jest wykonywane.

Możesz też zaktualizować kolejność zadań pojazdu, do którego jest przypisane, a potem usunąć zadanie z listy przystanków.

Określanie wyniku i lokalizacji zadania

Zamknięcie zadania nie oznacza powodzenia ani niepowodzenia. Oznacza ono, że zadanie nie jest już uważane za trwające. W przypadku śledzenia przesyłki ważne jest, aby wskazać rzeczywisty wynik zadania, aby można było poznać wyniki dostawy i prawidłowo naliczać opłaty za usługi. Po skonfigurowaniu tego ustawienia nie można zmienić wyniku zadania. Możesz jednak zmienić czas i lokalizację wyniku zadania po ich ustawieniu.

Zadania, które są w stanie ZAMKNIĘTE, mogą mieć stan ZAKOŃCZONO lub NIE UDAŁO SIĘ. Fleet Engine nalicza opłaty tylko za zadania dostawy ze stanem SUCCEEDED.

Zaznaczając wynik zadania, Fleet Engine automatycznie wypełnia lokalizację wyniku zadania ostatnią znaną lokalizacją pojazdu. Możesz zmienić ten sposób działania.

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

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

Wyszukaj pojazd

Możesz wyszukać pojazd za pomocą pakietu Driver SDK. Zanim wyszukasz pojazd, zainicjuj interfejs Delivery Driver API. Następnie możesz wyszukać pojazd, jak pokazano w przykładzie poniżej.

    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 wyszukiwać DeliveryVehicle tylko w przypadku identyfikatora pojazdu podanego podczas inicjowania interfejsu Delivery Driver API.