תחילת העבודה עם SDK של Drive ל-Android

דרישות מערכת מינימליות

במכשיר הנייד צריכה לפעול מערכת Android בגרסה 6.0 (API ברמה 23) ואילך.

הגדרת build וקשרי תלות

גרסאות 4.99 ואילך של Driver SDK זמינות ממאגר Google Maven.

Gradle

מוסיפים לקובץ build.gradle את הנתונים הבאים:

repositories {
    ...
    google()
}

Maven

מוסיפים לקובץ pom.xml את הנתונים הבאים:

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

הגדרות אישיות של פרויקט

כדי להשתמש ב-SDK של Drive, האפליקציה צריכה לטרגט ל-minSdkVersion 23 ואילך. מידע נוסף זמין בנתוני הגרסה.

כדי להריץ אפליקציה שנוצרה עם Driver SDK, צריך להתקין במכשיר ה-Android את Google Play Services.

הגדרת פרויקט הפיתוח

כדי להגדיר את פרויקט הפיתוח ולקבל מפתח API לפרויקט במסוף Google Cloud:

  1. יוצרים פרויקט חדש במסוף Google Cloud או בוחרים פרויקט קיים לשימוש עם Driver SDK. ממתינים מספר דקות עד שהפרויקט החדש מופיע במסוף Google Cloud.

  2. כדי להפעיל את אפליקציית ההדגמה, לפרויקט צריכה להיות גישה ל-SDK של מפות Google ל-Android. במסוף Google Cloud, בוחרים באפשרות APIs & Services > Library, ולאחר מכן מחפשים את ה-SDK של מפות Google ל-Android ומפעילים אותו.

  3. כדי לקבל מפתח API לפרויקט, לוחצים על APIs & Services > Credentials > Create credentials > API key. במאמר קבלת מפתח API תוכלו לקרוא מידע נוסף על קבלת מפתח API.

הוספת ה-SDK של Drive לאפליקציה

Driver SDK זמין ממאגר Google Maven. המאגר כולל את קובצי Project Object Model (.pom) של ה-SDK ואת קובצי Javadocs. כדי להוסיף את ה-SDK של Drive לאפליקציה:

  1. מוסיפים את התלות הבאה להגדרות של Gradle או Maven, ומחליפים את ה-placeholder VERSION_NUMBER בגרסה הנבחרת של Driver SDK.

    Gradle

    צריך להוסיף את הפרטים הבאים ל-build.gradle:

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

    Maven

    צריך להוסיף את הפרטים הבאים ל-pom.xml:

    <dependencies>
      ...
      <dependency>
        <groupId>com.google.android.libraries.mapsplatform.transportation</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>VERSION_NUMBER</version>
      </dependency>
    </dependencies>
    
  2. ה-SDK של מנהל ההתקן תלוי ב-Navigation SDK. התלות הזו מוגדרת כך שאם דרושה גרסה ספציפית של Navigation SDK, היא צריכה להיות מוגדרת באופן מפורש בקובץ תצורת ה-build כמו בדוגמה הבאה. השמטת גוש הקוד שהוזכר תאפשר לפרויקט להוריד תמיד את הגרסה האחרונה של ה-API של הניווט בגרסה הראשית. שימו לב שההתנהגויות המשולבות של הגרסאות העדכניות של Driver SDK ו-Navigation SDK עברו בדיקות קפדניות לפני שהושקו.

    חשוב לארגן את תצורת התלות של הפיתוח ולפרסם את הסביבות בהתאם.

    Gradle

    צריך להוסיף את הפרטים הבאים ל-build.gradle:

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

    Maven

    צריך להוסיף את הפרטים הבאים ל-pom.xml:

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

עדכון המניפסט של האפליקציה

אחרי שמוסיפים את Driver SDK לאפליקציה, אפשר לעדכן את המניפסט של האפליקציה על ידי עריכת קובץ AndroidManifest.xml של האפליקציה.

מוסיפים את מפתח ה-API בתוך הרכיב <application>. עליכם להשתמש במפתח ה-API של הפרויקט שקיבלתם כשהגדרתם את פרויקט הפיתוח.

לדוגמה, מחליפים את PASTE_YOUR_API_KEY_HERE במפתח ה-API במטא-נתונים הבאים של האפליקציה:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="PASTE_YOUR_API_KEY_HERE"/>

בדוגמה הבאה מוצג מניפסט מלא של אפליקציה לדוגמה:

<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="PASTE_YOUR_API_KEY_HERE"/>

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

הכללת הייחוסים הנדרשים באפליקציה

אם השתמשת ב-Drive SDK באפליקציה, עליך לכלול טקסט שיוך ורישיונות קוד פתוח בקטע ההודעות המשפטיות של האפליקציה. מומלץ לכלול את פרטי הייחוס כפריט בתפריט עצמאי או כחלק ממידע כללי.

פרטי הרישיונות מופיעים בקובץ "Third_party_Licenses.txt" בקובץ ה-AAR שאוחזר.

במאמר https://developers.google.com/android/guides/opensource מוסבר איך לכלול הודעות בקוד פתוח.

יחסי תלות

ב-Driver SDK נעשה שימוש ב-gRPC כדי לתקשר עם שרת Fleet Engine. אם עדיין לא הורדתם את gRPC, יכול להיות שתצטרכו להצהיר על יחסי התלות הבאים:

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

בלי יחסי התלות האלה, יהיו שגיאות בזמן הריצה ל-Driver SDK במהלך התקשורת עם שרת Fleet Engine.

אם אתם משתמשים ב-ProGuard כדי לבצע אופטימיזציה של גרסאות ה-build, יכול להיות שתצטרכו להוסיף את השורות הבאות לקובץ התצורה של ProGuard:

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

רמת ה-API המינימלית הנתמכת היא 23.

הפעלת ה-SDK

כדי לאתחל את האובייקט FleetEngine, נדרש מזהה ספק (בדרך כלל מזהה הפרויקט ב-Google Cloud). למידע נוסף על הגדרת הפרויקט ב-Google Cloud, קראו את המאמר אימות והרשאה.

לפני השימוש ב-Driver SDK, צריך לאתחל את הניווט SDK. כדי לאתחל את ה-SDK:

  1. מקבלים אובייקט Navigator מה-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. יוצרים אובייקט DriverContext, ומאכלסים את שדות החובה.

    DriverContext driverContext = DriverContext.builder(application)
                 .setProviderId(providerId)
                 .setVehicleId(vehicleId)
                 .setAuthTokenFactory(authTokenFactory)
                 .setNavigator(navigator)
                 .setRoadSnappedLocationProvider(
                     NavigationApi.getRoadSnappedLocationProvider(application))
                 .build()
    
  3. משתמשים באובייקט DriverContext כדי לאתחל את *DriverApi.

    DeliveryDriverApi driverApi = DeliveryDriverApi.createInstance(driverContext);
    
  4. מקבלים את ה-DeliveryVehicleReporter מאובייקט ה-API. (DeliveryVehicleReporter למשך NavigationVehicleReporter).

    DeliveryVehicleReporter vehicleReporter = driverApi.getDeliveryVehicleReporter();
    

אימות באמצעות AuthTokenFactory

כש-Driver SDK יוצר עדכוני מיקום, הוא צריך לשלוח את העדכונים האלה לשרת של Google Fleet Engine. כדי לאמת את הבקשות האלה, ה-SDK של הנהג מבצע קריאה למכונה AuthTokenFactory שסופקה על ידי המתקשר. המפעל אחראי ליצירת אסימוני האימות בזמן עדכון המיקום.

האופן שבו נוצרים אסימונים ספציפיים הוא ספציפי למצבו של כל מפתח. עם זאת, סביר להניח שההטמעה צריכה:

  • אחזר אסימון אימות, כנראה בפורמט JSON, משרת HTTPS.
  • ניתוח ושמירה של האסימון במטמון.
  • מרעננים את האסימון כשהתוקף שלו פג.

לפרטים על האסימונים הצפויים על ידי שרת Fleet Engine, ראו יצירת JSON Web Token (JWT) להרשאה.

הנה יישום שלד של AuthTokenManufacturer:

class JsonAuthTokenFactory implements AuthTokenFactory {
  String vehicleServiceToken;  // initially null
  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 URL(url).openStream()) {
      com.google.gson.JsonObject obj
          = new com.google.gson.JsonParser().parse(r);
      vehicleServiceToken = obj.get("VehicleServiceToken").getAsString();
      expiryTimeMs = obj.getAsLong("TokenExpiryMs");

      // 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 FleetEngine class will be notified and pass along the failed
      // update warning.
      throw new RuntimeException("Could not get auth token", e);
    }
  }
}

ההטמעה הספציפית הזו משתמשת בלקוח ה-HTTP המובנה של Java כדי לאחזר אסימון בפורמט JSON משרת האימות של המפתח. האסימון נשמר לשימוש חוזר. האסימון מאוחזר מחדש אם האסימון הישן נמצא בטווח של 10 דקות מזמן התפוגה שלו.

בהטמעה עשויה להתבצע פעולות שונות, למשל שימוש בשרשור ברקע כדי לרענן אסימונים.

החריגים ב-AuthTokenFactory נחשבים כזמניים, אלא אם הם מתרחשים באופן חוזר ונשנה. אחרי מספר ניסיונות, ה-SDK של Drive מניח שהשגיאה קבועה ומפסיק לשלוח עדכונים.

דיווח סטטוס ושגיאות עם StatusListener

מכיוון שה-Drive SDK מבצע פעולות ברקע, צריך להשתמש ב-StatusListener כדי להפעיל התראות כשמתרחשים אירועים מסוימים, כמו שגיאות, אזהרות או הודעות ניפוי באגים. שגיאות עשויות להיות זמניות (כמו BACKEND_CONNECTIVITY_ERROR), או לגרום להפסקה סופית של עדכוני מיקום (כמו VEHICLE_NOT_FOUND, מה שמעיד על שגיאה בהגדרה).

מספקים הטמעה אופציונלית של 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.
  }
}

הערות לגבי SSL/TLS

באופן פנימי, ההטמעה של Driver SDK משתמשת ב-SSL/TLS כדי לתקשר באופן מאובטח עם שרת Fleet Engine. יכול להיות שבגרסאות קודמות של Android (בגרסאות API 23 או גרסאות קודמות) יהיה צורך בתיקון SecurityProvider כדי לתקשר עם השרת. למידע נוסף על עבודה עם SSL ב-Android, קראו את המאמר עדכון ספק האבטחה להגנה מפני פרצות של SSL. המאמר מכיל גם דוגמאות קוד לתיקון ספק האבטחה.

הפעלת עדכוני מיקום

אחרי שיש מכונה של *VehicleReporter, זה פשוט מאוד:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

עדכוני מיקום נשלחים במרווחי זמן קבועים, אם אפשר. כל עדכון מיקום מציין גם שהרכב מחובר לאינטרנט.

כברירת מחדל, מרווח הזמן לדיווח הוא 10 שניות, אבל אפשר לשנות את מרווח הזמן לדיווח באמצעות FleetEngine.setLocationReportingInterval(long, TimeUnit). מרווח העדכון המינימלי הנתמך הוא 5 שניות. עדכונים תכופים יותר עלולים לגרום להאטת הבקשות ולשגיאות.

השבתה של עדכוני מיקום

בסיום משמרת הנהג, ניתן לעצור את עדכוני המיקום על ידי התקשרות אל DeliveryVehicleReporter.disableLocationTracking.

תרחישים לדוגמה לשימוש במודל מהימן

בקטע הזה מוסבר איך להשתמש ב-Driver SDK כדי להטמיע תרחישים נפוצים כשמשתמשים במודל המהימן.

יצירת רכב

אתם יכולים ליצור כלי רכב דרך Driver SDK.

לפני שיוצרים רכב, חשוב להפעיל את Delivery Driver API. צריך ליצור את מזהה הרכב יחד עם מזהי הרכב והספק שבהם נעשה שימוש במהלך האתחול של ה-SDK של הנהג. לאחר מכן יוצרים את הרכב כמו בדוגמה הבאה:

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

יצירת משימה לאיסוף משלוח

אתם יכולים ליצור משימה לאיסוף משלוח מ-Driver SDK.

לפני שיוצרים משימה, צריך להפעיל את Delivery Driver API. צריך ליצור את המשימה באמצעות מזהה הספק שצוין במהלך האתחול של ה-SDK של ה-Drive. לאחר מכן יוצרים את המשימה של איסוף המשלוח כמו בדוגמה הבאה. מידע נוסף על מזהי משימות זמין במאמר דוגמאות של מזהי משימות.

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

יצירת משימה של מסירת משלוח

אתם יכולים ליצור משימת מסירה של משלוח מ-Driver SDK.

לפני שיוצרים משימה, צריך להפעיל את Delivery Driver API. לאחר מכן יוצרים את המשימה של מסירת המשלוח כמו בדוגמה הבאה. מידע נוסף על מזהי משימות זמין במאמר דוגמאות של מזהי משימות.

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

חוסר זמינות מתוזמן

תוכלו ליצור ב-SDK של Driver SDK משימה שמציינת את חוסר הזמינות (לדוגמה, להפסקות לנהגים או לתדלוק ברכב). אי אפשר לכלול מזהה לצורכי מעקב במשימה מתוזמנת של אי-זמינות. אפשר גם לציין מיקום.

לפני שיוצרים משימה, צריך להפעיל את Delivery Driver API. לאחר מכן יוצרים את המשימה 'לא זמינות', כמו בדוגמה הבאה. מידע נוסף על מזהי משימות זמין במאמר דוגמאות של מזהי משימות.

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

עצירות מתוזמנות

אתם יכולים ליצור ב-SDK של Driver משימות של עצירה מתוזמנת. משימת עצירה מתוזמנת לא יכולה לכלול מזהה לצורכי מעקב.

לפני שיוצרים משימה, צריך להפעיל את Delivery Driver API. לאחר מכן יוצרים את משימת העצירה המתוזמנת, כמו בדוגמה הבאה. מידע נוסף על מזהי משימות זמין במאמר דוגמאות של מזהי משימות.

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

עדכון של סדר המשימות

תוכלו לעדכן את סדר הביצוע של משימות שהוקצו לרכב דרך ה-SDK של Drive.

עדכון של סדר המשימות גם מקצים משימות לרכב, אם הן לא הוקצו בעבר לרכב. נסגרות גם משימות שהוקצו לרכב וכבר לא בוצעו בהן שינויים בסדר הנכון. כשמקצים משימה לרכב אחר, אם הוא היה מוקצה בעבר לרכב אחר, מופיעה שגיאה. לפני שמקצים משימה לרכב החדש, צריך לסגור את המשימה הקיימת וליצור משימה חדשה.

אתם יכולים לעדכן את סדר המשימות מתי שתרצו.

לפני שמעדכנים את סדר המשימות ברכב, חשוב לוודא שהרכב והמשימות כבר נוצרו ב-Flet Engine. לאחר מכן, מעדכנים את סדר המשימות ברכב, כמו בדוגמה הבאה.

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

יכול להיות שיש חריגה שיכולה למנוע עדכון של המצב הפנימי של ה-SDK של Driver. במקרה כזה, צריך לפתור את הבעיה להתקשר שוב למספר setVehicleStops, עד שהשיחה תסתיים.

הבעיות האפשריות כוללות:

  • עצירות הרכב שצוינו לא תואמות לקו ביטול נעילה חוקי. רק הרכב הראשון של כלי הרכב יכול להיות בכל מצב של כלי רכב: 'חדש', 'ENROUTE' או 'ARRIVED'. עצירות של כלי רכב לאחר העצירה הנוכחית חייבות להיות במצב NEW VehicleStopState.

  • יכול להיות שהמשימות לא קיימות או שהן שייכות לרכב אחר.

  • הרכב לא קיים.

הרכב בדרך לתחנה הבאה

חובה להודיע למנוע ה-Fleet כשהרכב יוצא מתחנה ומתי מתחיל בניווט. אפשר לשלוח הודעה אל Fleet Engine דרך ה-SDK של Driver.

לפני שמיידעים את Fleet Engine שרכב יוצא מתחנה, צריך לוודא שהרכב מלא ומוגדר. לאחר מכן, עדכנו את Fleet Engine לגבי יציאת הרכב, כפי שמוצג בדוגמה הבאה.

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

יכול להיות שיש מקרה חריג שיכול למנוע עדכון של המצב הפנימי של ה-SDK של מנהל ההתקן. במקרה כזה, צריך לפתור את הבעיה להתקשר שוב אל enrouteToNextStop, עד שהפעולה תושלם.

הבעיות האפשריות כוללות:

  • לא הוגדר VehicleStops נותר ב-SDK של Drive.

הרכב מגיע לתחנה

חובה להודיע למנוע Fleet כאשר רכב מגיע לעצירה. אפשר לעדכן את Fleet Engine דרך ה-SDK של Drive.

לפני ש מודיעים ל-Feet Engine שכלי רכב הגיע לעצירה, צריך לוודא שהוגדרו עצירות הרכב. לאחר מכן יש להודיע ל-Flet Engine כשהרכב מגיע לעצירה, כפי שמוצג בדוגמה הבאה.

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

יש מקרה חריג שיכול למנוע עדכון של המצב הפנימי של ה-SDK של Drive. אם זה קורה, פותרים את הבעיה ומתקשרים שוב אל arrivedAtStop עד שהפעולה תושלם.

הבעיות האפשריות כוללות:

  • לא הוגדר VehicleStops נותר ב-SDK של Drive.

הרכב משלים עצירה

חובה לשלוח הודעה למנוע העצירה של כלי הרכב. כך כל המשימות שמשויכות לעצירה יוגדרו למצב 'סגור'. אפשר לעדכן את Fleet Engine מ-Driver SDK.

מיידעים את Fleet Engine שהרכב השלים את פעולת העצירה של הרכב, בדוגמה הבאה.

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

יש מקרה חריג שיכול למנוע עדכון של המצב הפנימי של ה-SDK של Drive. אם זה קורה, פותרים את הבעיה ומתקשרים שוב אל completedStop עד שהפעולה תושלם.

הבעיות האפשריות כוללות:

  • לא הוגדר VehicleStops נותר ב-SDK של Drive.

סגירת משימה

כדי לסגור משימה שהוקצתה לרכב, צריך להודיע ל-Feet Engine שהרכב השלים את העצירה של המשימה או להסיר אותה מרשימת העצירות של הרכב. כדי לעשות זאת, אפשר להגדיר את רשימת העצירות של הרכבים שנותרו באותו אופן שבו מעדכנים את סדר המשימות לגבי רכב מסוים.

אם למשימה עדיין לא הוקצה רכב וצריך לסגור אותה, צריך לעדכן אותה למצב 'סגור'. עם זאת, אי אפשר לפתוח מחדש משימה שנסגרה.

אם המשימה מסתיימת, היא לא מעידה על הצלחה או כישלון. המשמעות היא שהמשימה לא נמצאת יותר בטיפול. במעקב אחר משלוחים, חשוב לציין את התוצאה בפועל של המשימה כדי שאפשר יהיה להציג את תוצאת המסירה.

כדי שאפשר יהיה להשתמש ב-Driver SDK לסגירת המשימה, צריך להקצות את המשימה לרכב. כדי לסגור משימה שהוקצתה לרכב, צריך להודיע ל-Fleet Engine שהרכב השלים את העצירה במקום המשימה.

לחלופין, אפשר לעדכן את סדר המשימות ברכב שהמשימה מוקצית לו, ואז להסיר את המשימה הרצויה מרשימת העצירות.

הגדרה של תוצאת המשימה ומיקום התוצאה

אם המשימה מסתיימת, היא לא מעידה על הצלחה או כישלון. המשמעות היא שהמשימה לא נמצאת יותר בטיפול. במעקב אחרי משלוחים, חשוב לציין את התוצאה בפועל של המשימה כדי שאפשר יהיה להציג את תוצאת המסירה וכדי שיהיה חיוב תקין על השירותים. אחרי שמגדירים את המשימה, אי אפשר לשנות אותה. אבל אפשר לשנות את הזמן של תוצאת המשימה ואת המיקום של התוצאה אחרי שמגדירים אותן.

במשימות שנמצאות במצב 'סגור' אפשר להגדיר את התוצאה כ-'עבד' או כ'נכשל'. Fleet Engine טוען רק משימות מסירה במצב של הפעלה.

בזמן סימון התוצאה של משימה, Fleet Engine ממלא באופן אוטומטי את מיקום המשימה לפי המיקום הידוע האחרון של כלי הרכב. אפשר לשנות את ההתנהגות הזו על ידי קריאה ל-Feet Engine. שימו לב שאי אפשר להגדיר את המיקום של תוצאת המשימה באמצעות Driver SDK.

דוגמת הקוד הבאה ממחישה איך להשתמש ב-SDK של Drive כדי להגדיר תוצאה וחותמת זמן של המשימה.

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

חיפוש כלי רכב

אתם יכולים לחפש כלי רכב ב-Driver SDK. לפני שמחפשים כלי רכב, חשוב להפעיל את Delivery Driver API. לאחר מכן תוכלו לחפש את הרכב כמו בדוגמה הבאה.

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 רק את DeliveryVehicle מזהה הרכב שסופק במהלך אתחול ה- Delivery של Driver API.