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

שימוש נכון בפרטי מיקום יכול להועיל למשתמשים באפליקציה שלכם. לדוגמה, אם האפליקציה עוזרת למשתמש להתמצא בזמן הליכה או נהיגה, או אם האפליקציה עוקבת אחרי מיקום של נכסים, היא צריכה לקבל את המיקום של המכשיר במרווחי זמן קבועים. בנוסף למיקום הגיאוגרפי (קו רוחב וקו אורך), יכול להיות שתרצו לספק למשתמש מידע נוסף כמו הכיוון (הכיוון האופקי של הנסיעה), הגובה או המהירות של המכשיר. המידע הזה, ועוד, זמין באובייקט Location שאפליקציה יכולה לאחזר מספק המיקום המשולב. בתגובה, ה-API מעדכן את האפליקציה שלכם מעת לעת עם המיקום הכי מדויק שזמין, על סמך ספקי המיקום שזמינים כרגע, כמו Wi-Fi ו-GPS (מערכת למיקום גלובלי). הדיוק של המיקום נקבע על ידי הספקים, הרשאות המיקום שביקשתם והאפשרויות שהגדרתם בבקשת המיקום.

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

קבלת המיקום הידוע האחרון

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

שליחת בקשת מיקום

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

בהתאם לצורת הבקשה, ספק המיקום המשולב מפעיל את שיטת הקריאה החוזרת LocationCallback.onLocationResult() ומעביר לה רשימה של אובייקטים מסוג Location, או מנפיק PendingIntent שמכיל את המיקום בנתונים המורחבים שלו. רמת הדיוק והתדירות של העדכונים מושפעות מהרשאות המיקום שביקשתם ומהאפשרויות שהגדרתם באובייקט בקשת המיקום.

בשיעור הזה נסביר איך לקבל את העדכון באמצעות גישת הקריאה החוזרת (callback) של LocationCallback. מתקשרים אל requestLocationUpdates(), מעבירים את המופע של האובייקט LocationRequest, ואת LocationCallback. מגדירים שיטת startLocationUpdates() כמו בדוגמת הקוד הבאה:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

private fun startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper())
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

private void startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper());
}

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

הגדרת קריאה חוזרת לעדכון המיקום

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

Kotlin

private lateinit var locationCallback: LocationCallback

// ...

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

    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            for (location in locationResult.locations){
                // Update UI with location data
                // ...
            }
        }
    }
}

Java

private LocationCallback locationCallback;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                // Update UI with location data
                // ...
            }
        }
    };
}

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

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

כדי להפסיק את עדכוני המיקום, צריך לבצע קריאה ל-removeLocationUpdates() ולהעביר לו LocationCallback, כמו בדוגמת הקוד הבאה:

Kotlin

override fun onPause() {
    super.onPause()
    stopLocationUpdates()
}

private fun stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

Java

@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

private void stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback);
}

משתמשים בערך בוליאני, requestingLocationUpdates, כדי לעקוב אחרי המצב הנוכחי של עדכוני המיקום. בשיטה onResume() של הפעילות, בודקים אם עדכוני המיקום פעילים כרגע, ומפעילים אותם אם לא:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

שמירת מצב הפעילות

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

דוגמת הקוד הבאה מראה איך להשתמש בקריאה החוזרת (callback) של הפעילות onSaveInstanceState() כדי לשמור את מצב המופע:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates)
    super.onSaveInstanceState(outState)
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
            requestingLocationUpdates);
    // ...
    super.onSaveInstanceState(outState);
}

מגדירים updateValuesFromBundle() שיטה לשחזור הערכים שנשמרו מהמופע הקודם של הפעילות, אם הם זמינים. מבצעים קריאה ל-method מתוך ה-method‏ onCreate() של הפעילות, כמו בדוגמת הקוד הבאה:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    updateValuesFromBundle(savedInstanceState)
}

private fun updateValuesFromBundle(savedInstanceState: Bundle?) {
    savedInstanceState ?: return

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY)
    }

    // ...

    // Update UI to match restored state
    updateUI()
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    updateValuesFromBundle(savedInstanceState);
}

private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        return;
    }

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY);
    }

    // ...

    // Update UI to match restored state
    updateUI();
}

מידע נוסף על שמירת מצב המופע זמין במאמר בנושא פעילות ב-Android.

הערה: כדי לאחסן את ההעדפות של המשתמש בצורה קבועה יותר, אפשר לאחסן אותן בSharedPreferences של האפליקציה. מגדירים את ההעדפה המשותפת בשיטת onPause() של הפעילות, ומאחזרים את ההעדפה ב-onResume(). מידע נוסף על שמירת העדפות זמין במאמר בנושא שמירת קבוצות של זוגות מפתח/ערך.

מקורות מידע נוספים

מידע נוסף זמין במשאבים הבאים:

טעימות