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

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

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

אחזור המיקום הידוע האחרון

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

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

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

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

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

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

ספק המיקום המשולב מפעיל את שיטת הקריאה החוזרת 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
                // ...
            }
        }
    };
}

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

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

בדוגמת הקוד הבאה מוסבר איך להשתמש ב-callbak של הפעילות 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(). למידע נוסף על שמירת ההעדפות, קראו את המאמר שמירת קבוצות של מפתחות-ערכים.

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

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

דוגמיות