תחילת העבודה עם 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>

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

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

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

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

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

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

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

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

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

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

  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.driver</groupId>
        <artifactId>transportation-driver</artifactId>
        <version>[VERSION_NUMBER]</version>
      </dependency>
    </dependencies>
    
  2. ה-SDK של מנהל התקן תלוי ב-Navigation SDK, התלות הזו מוגדרת כך שאם נדרשת גרסה ספציפית של Navigation SDK, היא צריכה מוגדר באופן מפורש בקובץ תצורת build, כמו בדוגמה הבאה, אם לא תשמיט את בלוק הקוד שצוין, הפרויקט תמיד ירד את הגרסה האחרונה של SDK ניווט בגרסה הראשית. חשוב לשים לב שההתנהגויות המשולבות של הגרסאות האחרונות של Driver SDK ה-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>
    

הוספה של מפתח ה-API לאפליקציה

אחרי שמוסיפים את Driver SDK לאפליקציה, מוסיפים לאפליקציה את מפתח ה-API. שלך חייב להשתמש במפתח ה-API של הפרויקט שקיבלתם להגדיר פרויקט פיתוח.

בקטע הזה מוסבר איך לאחסן את מפתח ה-API כדי שיהיה מאובטח יותר שהאפליקציה שלך מפנה אליו. אין לבדוק את הגרסה של מפתח ה-API במערכת הבקרה. צריך לאחסן אותו בקובץ local.properties, שנמצא בתיקיית השורש של הפרויקט. לקבלת מידע נוסף על קובץ אחד (local.properties), לעיון קובצי מאפייני Gradle.

כדי לייעל את המשימה הזו, פלאגין של Secrets Gradle ל-Android. יש לבצע את התהליך הזה כדי להתקין את הפלאגין Secrets Gradle ולאחסן אותו באופן מאובטח במפתח ה-API.

  1. פותחים את קובץ build.gradle ברמה הבסיסית (root) ומוסיפים את הקוד הבא אל רכיב dependencies מתחת ל-buildscript.

    מגניב

    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. פותחים את הקובץ build.gradle ברמת האפליקציה ומוסיפים את הקוד הבא אל רכיב plugins.

    מגניב

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

    Kotlin

    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
    
  3. מסנכרנים את הפרויקט עם Gradle.

  4. פותחים את local.properties בספרייה ברמת הפרויקט ומוסיפים את באמצעות הקוד הבא. חשוב להחליף את YOUR_API_KEY במפתח ה-API.

    MAPS_API_KEY=YOUR_API_KEY
    
  5. בקובץ AndroidManifest.xml, עוברים אל com.google.android.geo.API_KEY ולעדכן את המאפיין android:value באופן הבא:

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

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

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

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

אם משתמשים ב-Driver SDK באפליקציה, צריך לכלול את ה-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'
}

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

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

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

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

הפעלת ה-SDK

צריך מזהה ספק (בדרך כלל מזהה הפרויקט ב-Google Cloud) כדי צריך לאתחל את האובייקט DriverContext. לפרטים נוספים על הגדרת לפרויקט ב-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 יוצר עדכוני מיקום, צריך לשלוח את העדכונים האלה אל השרת של Fleet Engine. כדי לאמת את הבקשות האלה, ה-SDK של Drive שולח קריאות למקבל הקריאה החוזרת (callr) מופע של AuthTokenFactory. המפעל אחראי על יצירת אסימוני האימות במיקום שעת העדכון.

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

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

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

זהו הטמעת בסיס של AuthTokenFactory:

class JsonAuthTokenFactory implements AuthTokenFactory {
  private String vehicleServiceToken;  // initially null
  private long expiryTimeMs = 0;
  private String vehicleId;

  // 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) {
    String vehicleId = requireNonNull(context.getVehicleId());

    if (System.currentTimeMillis() > expiryTimeMs || !vehicleId.equals(this.vehicleId)) {
      // The token has expired, go get a new one.
      fetchNewToken(vehicleId);
    }

    return vehicleServiceToken;
  }

  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;
      this.vehicleId = vehicleId;
    } 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);
    }
  }
}

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

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

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

דיווח סטטוס ושגיאות באמצעות StatusListener

מאחר ש-Driver 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, ראו ספק GMS לאבטחה. המאמר גם מכיל דוגמאות קוד לתיקון ספק האבטחה.

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

ברגע שיש לך מכונה של *VehicleReporter, הפעלת עדכוני מיקום פשוט:

DeliveryVehicleReporter reporter = ...;

reporter.enableLocationTracking();

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

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

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

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

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

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

יצירת רכב

אתם יכולים ליצור כלי רכב מה-Driver SDK.

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

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 של הנהג. ביטול זמינות מתוזמן לא ניתן לכלול מזהה לצורכי מעקב. אפשר גם לציין מיקום.

לפני שיוצרים משימה, צריך לוודא לאתחל את 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.
}

תחנות מתוכננות

אפשר ליצור משימה של עצירה מתוזמנת ב-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)
       .setTaskType(TaskType.DELIVERY_SCHEDULED_STOP)
       .build();
    try {
       DeliveryTask task = taskManager.createTask(request).get();
       // Handle CreateTaskRequest DeliveryTask response.
    } catch (Exception e)  {
       // Handle CreateTaskRequest error.
    }

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

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

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

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

לפני שמעדכנים את סדר המשימות של רכב, צריך לוודא שהרכב משימות כבר נוצרו ב-Fleet 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 של מנהל ההתקן. במקרה כזה, צריך לפתור את הבעיה ואז להתקשר שוב אל setVehicleStops עד שהשיחה תתבצע בהצלחה.

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

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

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

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

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

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

לפני שמעבירים הודעה ל-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.
    }

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

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

  • לא הוגדר עוד VehicleStops ב-Driver SDK.

רכב מגיע בעצירה

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

לפני שמעדכנים את 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.
// 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 state. במקרה כזה, צריך לפתור את הבעיה ואז להתקשר שוב אל arrivedAtStop עד שזה יצליח.

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

  • לא הוגדר עוד VehicleStops ב-Driver SDK.

הרכב עומד בעצירה

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

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

    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 state. במקרה כזה, צריך לפתור את הבעיה ואז להתקשר שוב אל completedStop עד שזה יצליח.

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

  • לא הוגדר עוד VehicleStops ב-Driver SDK.

סגירת משימה

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

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

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

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

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

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

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

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

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

בדוגמה הבאה אפשר לראות איך להשתמש ב-Driver SDK כדי להגדיר תוצאת משימה. וחותמת זמן. אי אפשר להגדיר את מיקום תוצאת המשימה באמצעות 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.
    }

חיפוש כלי רכב

אתם יכולים לחפש רכב ב-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.