שינוי הגדרות המיקום

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

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

הגדרת שירותי המיקום

כדי להשתמש בשירותי המיקום שמסופקים על ידי Google Play Services ובספק המיקום המשולב, צריך לחבר את האפליקציה באמצעות Settings Client, ואז לבדוק את הגדרות המיקום הנוכחיות ולהנחות את המשתמש להפעיל את ההגדרות הנדרשות אם צריך.

אפליקציות שהתכונות שלהן משתמשות בשירותי מיקום צריכות לבקש הרשאות מיקום, בהתאם לתרחישי השימוש של התכונות האלה.

הגדרת בקשה למיקום

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

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

setPriority() – השיטה הזו מגדירה את העדיפות של הבקשה, וכך שירותי המיקום של Google Play Services מקבלים רמז ברור לגבי מקורות המיקום שבהם כדאי להשתמש. יש תמיכה בערכים הבאים:

  • PRIORITY_BALANCED_POWER_ACCURACY – משתמשים בהגדרה הזו כדי לבקש דיוק מיקום ברמת בלוק בעיר, כלומר דיוק של כ-100 מטרים. הדיוק הזה נחשב לרמה גסה, וסביר להניח שהוא יצרוך פחות חשמל. כשההגדרה הזו מופעלת, שירותי המיקום כנראה ישתמשו במיקום של נקודות Wi-Fi לשיתוף אינטרנט ובמיקום של אנטנות סלולריות. עם זאת, חשוב לזכור שהבחירה של ספק המיקום תלויה בגורמים רבים אחרים, כמו המקורות הזמינים.
  • PRIORITY_HIGH_ACCURACY – משתמשים בהגדרה הזו כדי לבקש את המיקום הכי מדויק שאפשר. כשההגדרה הזו מופעלת, שירותי המיקום נוטים יותר להשתמש ב-GPS כדי לקבוע את המיקום.
  • PRIORITY_LOW_POWER – משתמשים בהגדרה הזו כדי לבקש דיוק ברמת העיר, כלומר דיוק של כ-10 קילומטרים. הדיוק הזה נחשב לרמה גסה, וסביר להניח שהוא יצרוך פחות חשמל.
  • PRIORITY_PASSIVE – משתמשים בהגדרה הזו אם רוצים להקטין את ההשפעה על צריכת החשמל, אבל רוצים לקבל עדכוני מיקום כשהם זמינים. בהגדרה הזו, האפליקציה לא מפעילה עדכוני מיקום, אבל מקבלת מיקומים שהופעלו על ידי אפליקציות אחרות.

יוצרים את בקשת המיקום ומגדירים את הפרמטרים כמו בדוגמת הקוד הבאה:

Kotlin

  fun createLocationRequest() {
    val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
        .setMinUpdateIntervalMillis(5000)
        .build()
}

Java

  protected void createLocationRequest() {
    LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
            .setMinUpdateIntervalMillis(5000)
            .build();
}

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

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

קבלת הגדרות המיקום הנוכחיות

אחרי שמתחברים ל-Google Play Services ול-API של שירותי המיקום, אפשר לקבל את הגדרות המיקום הנוכחיות של המכשיר של המשתמש. כדי לעשות את זה, יוצרים LocationSettingsRequest.Builder ומוסיפים אליו בקשה אחת או יותר למיקום. בקטע הקוד הבא מוצג אופן ההוספה של בקשת המיקום שנוצרה בשלב הקודם:

Kotlin

val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
     .addLocationRequest(locationRequest);

לאחר מכן בודקים אם הגדרות המיקום הנוכחיות מתאימות:

Kotlin

val builder = LocationSettingsRequest.Builder()

// ...

val client: SettingsClient = LocationServices.getSettingsClient(this)
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())

Java

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();

// ...

SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());

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

בקשה מהמשתמש לשנות את הגדרות המיקום

כדי לקבוע אם הגדרות המיקום מתאימות לבקשת המיקום, מוסיפים OnFailureListener לאובייקט Task שמאמת את הגדרות המיקום. לאחר מכן, בודקים אם האובייקט Exception שמועבר לשיטה onFailure() הוא מופע של המחלקה ResolvableApiException, מה שמצביע על כך שצריך לשנות את ההגדרות. לאחר מכן, מציגים תיבת דו-שיח שמבקשת מהמשתמש הרשאה לשנות את הגדרות המיקום באמצעות קריאה ל- startResolutionForResult().

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

Kotlin

task.addOnSuccessListener { locationSettingsResponse ->
    // All location settings are satisfied. The client can initialize
    // location requests here.
    // ...
}

task.addOnFailureListener { exception ->
    if (exception is ResolvableApiException){
        // Location settings are not satisfied, but this can be fixed
        // by showing the user a dialog.
        try {
            // Show the dialog by calling startResolutionForResult(),
            // and check the result in onActivityResult().
            exception.startResolutionForResult(this@MainActivity,
                    REQUEST_CHECK_SETTINGS)
        } catch (sendEx: IntentSender.SendIntentException) {
            // Ignore the error.
        }
    }
}

Java

task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
    }
});

task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
});

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