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

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

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

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

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

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

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

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

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

כדי לקבל מידע נוסף, אפשר להיעזר במקורות המידע הבאים:

דוגמאות