סקירה כללית של Fence API

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

אפשר להשתמש ב-Fence API כדי להגדיר גדרות על סמך אותות הקשריים, כמו:

  • המיקום הנוכחי של המשתמש (קו רוחב/קו אורך)
  • הפעילות הנוכחית של המשתמש, כמו הליכה או נהיגה.
  • תנאים ספציפיים למכשיר, כמו אם האוזניות מחוברות.
  • קרבה למשואות (beacons) בסביבה

‫Fence API מאפשר לכם לשלב כמה אותות הקשר כדי ליצור גדרות עם האופרטורים הבוליאניים AND,‏ OR ו-NOT. לאחר מכן, האפליקציה מקבלת קריאות חוזרות (callback) בכל פעם שהתנאים של הגדרת הגדר מתקיימים. הנה כמה דוגמאות לגדרות אפשריות:

  • משתמש מחבר אוזניות ומתחיל ללכת.
  • משתמש נכנס לגדר הגיאוגרפית של 100 מטרים לפני השעה 17:00 ביום חול.
  • משתמש נכנס לטווח של משדר BLE ספציפי.

בדוגמה הבאה אפשר לראות איך מגדירים גדר וירטואלית שמופעלת בכל פעם שהמשתמש הולך:

AwarenessFence walkingFence = DetectedActivityFence.during(DetectedActivityFence.WALKING);

אחרי שמגדירים גדר וירטואלית, צריך לבצע את הפעולות הבאות:

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

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

Awareness.getFenceClient(this).updateFences(new FenceUpdateRequest.Builder()
    .addFence(FENCE_KEY, exercisingWithHeadphonesFence, mPendingIntent)
    .build())
    .addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            Log.i(TAG, "Fence was successfully registered.");
        }
    })
    .addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.e(TAG, "Fence could not be registered: " + e);
        }
    });
public class FenceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        FenceState fenceState = FenceState.extract(intent);

        if (TextUtils.equals(fenceState.getFenceKey(), FENCE_KEY)) {
            String fenceStateStr;
            switch (fenceState.getCurrentState()) {
                case FenceState.TRUE:
                    fenceStateStr = "true";
                    break;
                case FenceState.FALSE:
                    fenceStateStr = "false";
                    break;
                case FenceState.UNKNOWN:
                    fenceStateStr = "unknown";
                    break;
                default:
                    fenceStateStr = "unknown value";
            }
            mLogFragment.getLogView().println("Fence state: " + fenceStateStr);
        }
    }
}