מעקב אחר נסיעה ב-Android

בחירת פלטפורמה: Android iOS JavaScript

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

במאמר הזה מוסבר איך התהליך הזה פועל.

לפני שמתחילים

חשוב לוודא שהגדרתם את הפריטים הבאים:

  • שירותי ה-Backend של אפליקציית הצרכנים שלכם מוכנים, והשירותים שלכם להתאמת צרכנים לכלי רכב פועלים.

  • הגדרתם מפה לאפליקציה.

התחלת מעקב אחרי נסיעה

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

דוגמת הקוד הבאה מראה איך להתחיל לעקוב אחרי נסיעה אחרי שהתצוגה נטענת.

Java

public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {

  // Class implementation

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a TripModel instance to listen for updates to the trip specified by this trip name.
    String tripName = ...;
    TripModelManager tripModelManager = consumerApi.getTripModelManager();
    TripModel tripModel = tripModelManager.getTripModel(tripName);

    // Create a JourneySharingSession instance based on the TripModel.
    JourneySharingSession session = JourneySharingSession.createInstance(tripModel);

    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session);

    // Register for trip update events.
    tripModel.registerTripCallback(new TripModelCallback() {
      @Override
      public void onTripETAToNextWaypointUpdated(
          TripInfo tripInfo, @Nullable Long timestampMillis) {
        // ...
      }

      @Override
      public void onTripActiveRouteRemainingDistanceUpdated(
          TripInfo tripInfo, @Nullable Integer distanceMeters) {
        // ...
      }

      // ...
    });
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}

Kotlin

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Create a TripModel instance to listen for updates to the trip specified by this trip name.
    val tripName = "tripName"
    val tripModelManager = consumerApi.getTripModelManager()
    val tripModel = tripModelManager.getTripModel(tripName)

    // Create a JourneySharingSession instance based on the TripModel.
    val session = JourneySharingSession.createInstance(tripModel)

    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session)

    // Register for trip update events.
    tripModel.registerTripCallback(
      object : TripModelCallback() {
        override fun onTripETAToNextWaypointUpdated(
          tripInfo: TripInfo,
          timestampMillis: Long?,
        ) {
          // ...
        }

        override fun onTripActiveRouteRemainingDistanceUpdated(
          tripInfo: TripInfo,
          distanceMeters: Int?,
        ) {
          // ...
        }

      // ...
    })
  }

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

עדכון ההתקדמות בנסיעה

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

  1. רישום מעבד אירוע באובייקט TripModel.

    Java

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    String tripName = ...;
    TripModelManager tripModelManager = consumerApi.getTripModelManager();
    TripModel tripModel = tripModelManager.getTripModel(tripName);
    
    // Create a JourneySharingSession instance based on the TripModel.
    JourneySharingSession session = JourneySharingSession.createInstance(tripModel);
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session);
    
    // Register for trip update events.
    tripModel.registerTripCallback(new TripModelCallback() {
    @Override
    public void onTripETAToNextWaypointUpdated(
            TripInfo tripInfo, @Nullable Long timestampMillis) {
          // ...
    }
    
    @Override
    public void onTripActiveRouteRemainingDistanceUpdated(
            TripInfo tripInfo, @Nullable Integer distanceMeters) {
          // ...
    }
    
    // ...
    });
    

    Kotlin

    // Create a TripModel instance for listening to updates to the trip specified by this trip name.
    val tripName = "tripName"
    val tripModelManager = consumerApi.getTripModelManager()
    val tripModel = tripModelManager.getTripModel(tripName)
    
    // Create a JourneySharingSession instance based on the TripModel.
    val session = JourneySharingSession.createInstance(tripModel)
    
    // Add the JourneySharingSession instance on the map for updating the UI.
    consumerController.showSession(session)
    
    // Register for trip update events.
    tripModel.registerTripCallback(
      object : TripModelCallback() {
        override fun onTripETAToNextWaypointUpdated(
          tripInfo: TripInfo,
          timestampMillis: Long?,
        ) {
          // ...
        }
    
        override fun onTripActiveRouteRemainingDistanceUpdated(
          tripInfo: TripInfo,
          distanceMeters: Int?,
        ) {
          // ...
        }
    
      // ...
    })
    
  2. מגדירים את המאזין לנסיעה באמצעות TripModelOptions.

    Java

    // Set refresh interval to 2 seconds.
    TripModelOptions tripOptions =
          TripModelOptions.builder().setRefreshIntervalMillis(2000).build();
    tripModel.setTripModelOptions(tripOptions);
    

    Kotlin

    // Set refresh interval to 2 seconds.
    val tripOptions = TripModelOptions.builder().setRefreshIntervalMillis(2000).build()
    tripModel.setTripModelOptions(tripOptions)
    

הפסקת המעקב אחרי נסיעה

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

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

Java

public class MainActivity extends AppCompatActivity
    implements ConsumerViewModel.JourneySharingListener  {

  // Class implementation

  @Override
  protected void onDestroy() {
    super.onDestroy();

    if (journeySharingSession != null) {
      journeySharingSession.stop();
    }
  }
}

Kotlin

class SampleAppActivity : AppCompatActivity(), ConsumerViewModel.JourneySharingListener {

  // Class implementation

  override fun onDestroy() {
    super.onDestroy()

    journeySharingSession?.stop()
  }
}

טיפול בשגיאות בנסיעות

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

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

HTTP הכנסה לקליק תיאור
400 INVALID_ARGUMENT הלקוח ציין שם נסיעה לא חוקי. שם הנסיעה צריך להיות בפורמט providers/{provider_id}/trips/{trip_id}. הערך של provider_id צריך להיות מזהה פרויקט Cloud שבבעלות ספק השירות.
401 לא מאומת השגיאה הזו מופיעה אם אין פרטי כניסה תקפים לאימות. לדוגמה, אם אסימון ה-JWT חתום ללא מזהה נסיעה או אם תוקף אסימון ה-JWT פג.
403 PERMISSION_DENIED השגיאה הזו מתקבלת אם ללקוח אין הרשאה מספקת (לדוגמה, משתמש עם תפקיד צרכן מנסה להתקשר אל updateTrip), אם אסימון ה-JWT לא תקין או אם ה-API לא מופעל בפרויקט הלקוח. יכול להיות שאסימון ה-JWT חסר או שהאסימון חתום עם מזהה נסיעה שלא תואם למזהה הנסיעה המבוקש.
429 RESOURCE_EXHAUSTED מכסת המשאבים היא אפס או שקצב התנועה חורג מהמגבלה.
503 UNAVAILABLE השירות לא זמין. בדרך כלל השרת מושבת.
504 DEADLINE_EXCEEDED המועד האחרון לשליחת הבקשה חלף. השגיאה הזו מתרחשת רק אם המתקשר מגדיר מועד אחרון שהוא קצר יותר מהמועד האחרון שמוגדר כברירת מחדל לשיטה (כלומר, המועד האחרון שנדרש לא מספיק לשרת כדי לעבד את הבקשה), והבקשה לא הסתיימה לפני המועד האחרון.

טיפול בשגיאות ב-Consumer SDK

ערכת Consumer SDK שולחת שגיאות בעדכוני נסיעה לאפליקציית הצרכן באמצעות מנגנון של קריאה חוזרת (callback). פרמטר הקריאה החוזרת הוא סוג החזרה שספציפי לפלטפורמה (TripUpdateError ב-Android ו-NSError ב-iOS).

חילוץ קודי סטטוס

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

Java

אפשר לחלץ קוד סטטוס של gRPC שמספק פרטים על השגיאה מתוך TripUpdateError שמוחזר מ-onTripUpdateError().

// Called when there is a trip update error.
@Override
public void onTripUpdateError(TripInfo tripInfo, TripUpdateError error) {
  Status.Code code = error.getStatusCode();
}

Kotlin

אפשר לחלץ קוד סטטוס של gRPC שמספק פרטים על השגיאה מתוך TripUpdateError שמוחזר מ-onTripUpdateError().

// Called when there is a trip update error.
override fun onTripUpdateError(tripInfo: TripInfo, error: TripUpdateError) {
  val code = error.getStatusCode()
}

הסבר על קודי סטטוס

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

שגיאות בחיבור לשרת ולרשת

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

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

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

שגיאות בצד הלקוח

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

קוד סטטוסתיאור
INVALID_ARGUMENT אפליקציית הצרכן ציינה שם נסיעה לא חוקי. שם הנסיעה צריך להיות בפורמט providers/{provider_id}/trips/{trip_id}.
NOT_FOUND הנסיעה אף פעם לא נוצרה.
PERMISSION_DENIED לאפליקציית הצרכן אין הרשאות מספיקות. השגיאה הזו מתרחשת במקרים הבאים:
  • לאפליקציה לצרכן אין הרשאות
  • ה-SDK לצרכנים לא מופעל בפרויקט במסוף Google Cloud.
  • טוקן ה-JWT חסר או לא תקין.
  • אסימון ה-JWT חתום עם מזהה נסיעה שלא תואם לנסיעה המבוקשת.
RESOURCE_EXHAUSTED מכסת המשאבים היא אפס, או שקצב זרימת התנועה חורג ממגבלת המהירות.
לא מאומת האימות של הבקשה נכשל בגלל טוקן JWT לא תקין. השגיאה הזו מתרחשת אם אסימון ה-JWT נחתם ללא מזהה נסיעה, או אם תוקף אסימון ה-JWT פג.