מאז Android 6.0 Marshmallow, מערכת Android משתמשת במודל הרשאות שמייעל את תהליך ההתקנה והעדכון האוטומטי של האפליקציות. הבקשה להרשאות מוצגת בזמן ההפעלה ולא לפני התקנת האפליקציה. בנוסף, המשתמשים יכולים לבחור שלא לאשר הרשאות ספציפיות. כדי לאפשר למשתמשים את הגמישות הזו, צריך לוודא שהאפליקציה מתנהגת כמו שצריך כשמשתמש מפעיל או משבית הרשאה ספציפית.
ל-Google Play Services עצמו יש הרשאות זמן ריצה שהמשתמשים יכולים לבחור לדחות בנפרד מההרשאות שהאפליקציה שלכם מבקשת באופן ספציפי. Google Play Services מקבל באופן אוטומטי את כל ההרשאות שהוא צריך כדי לתמוך בממשקי ה-API שלו. עם זאת, האפליקציה עדיין צריכה לבדוק ולבקש הרשאות בזמן הריצה לפי הצורך, ולטפל בשגיאות בצורה מתאימה במקרים שבהם משתמש דחה את ההרשאה של שירותי Google Play שנדרשת ל-API שהאפליקציה משתמשת בו.
מומלץ לנהל את ציפיות המשתמשים בהגדרת הרשאות שהסביבה עשויה לדרוש. השיטות המומלצות הבאות יעזרו לכם להימנע מבעיות פוטנציאליות.
דרישות מוקדמות
צריך להצהיר על הרשאות בקובץ AndroidManifest.xml
.
לדוגמה:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
הנחיות
אימות הרשאות לפני הפעלת ממשקי API
אחרי שמצהירים על ממשקי ה-API שרוצים להשתמש בהם בקובץ AndroidManifest.xml
, צריך לוודא שיש את ההרשאה הנדרשת לפני שמבצעים קריאה ל-API. אפשר לעשות את זה באמצעות השיטה checkSelfPermission
של ActivityCompat
או ContextCompat
.
אם הקריאה מחזירה את הערך false, המשמעות היא שההרשאות לא ניתנו וצריך להשתמש ב-requestPermissions
כדי לבקש אותן. התשובה לכך מוחזרת בקריאה חוזרת (callback) שתוצג בשלב הבא.
לדוגמה:
Kotlin
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } else { // permission has been granted, continue as usual val locationResult = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request Permissions Now ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION_CODE); } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
הטמעה של הקריאה החוזרת (callback) לבקשת הרשאה
אם המשתמש לא העניק את ההרשאה שהאפליקציה צריכה, צריך לקרוא לשיטה requestPermissions
כדי לבקש מהמשתמש להעניק אותה. התגובה של המשתמש מתועדת בקריאה החוזרת (callback) של onRequestPermissionsResult
. באפליקציה שלכם צריך להטמיע את הפונקציה הזו ולבדוק תמיד את ערכי ההחזרה, כי יכול להיות שהבקשה תידחה או תבוטל. אפשר גם לבקש ולבדוק כמה הרשאות בבת אחת – בדוגמה הבאה נבדקת רק הרשאה אחת.
Kotlin
fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if (grantResults.singleOrNull() == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to val locationResult: Task = LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation // Request the last known location. } else { // Permission was denied or request was cancelled } } }
Java
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_LOCATION_PERMISSION_CODE) { if(grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // We can now safely use the API we requested access to TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); // Request the last known location. } else { // Permission was denied or request was cancelled } } }
הצגת ההסבר להרשאה
אם ההרשאות שהאפליקציה מבקשת נחוצות לתכונות הליבה של האפליקציה, והמשתמש דחה בעבר את בקשת ההרשאה, האפליקציה צריכה להציג הסבר נוסף לפני בקשת ההרשאה שוב. המשתמשים נוטים יותר להעניק הרשאות כשהם מבינים למה ההרשאה נדרשת ומה התועלת המיידית שלהם.
במקרה כזה, לפני שמתקשרים אל requestPermissions
, צריך להתקשר אל shouldShowRequestPermissionRationale
. אם הפונקציה מחזירה true, צריך ליצור ממשק משתמש להצגת הקשר נוסף להרשאה.
לדוגמה, הקוד יכול להיראות כך:
Kotlin
private const val REQUEST_LOCATION_PERMISSION_CODE = 2 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now if ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION ) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION_CODE) } } else { // Permission has already been granted, continue as usual val locationResult: Task= LocationServices .getFusedLocationProviderClient(this /* Context */) .lastLocation }
Java
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Check Permissions Now private static final int REQUEST_LOCATION_PERMISSION_CODE = 2; if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Display UI and wait for user interaction } else { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.LOCATION_FINE}, REQUEST_LOCATION_PERMISSION_CODE); } } else { // permission has been granted, continue as usual TasklocationResult = LocationServices .getFusedLocationProviderClient(this /** Context */) .getLastLocation(); }
קריאות ל-Google Play Services API יציגו אוטומטית תיבת דו-שיח (אם הלקוח הוא מופע של Activity
) או התראה במגש המערכת (אם הלקוח הוא מופע של Context
). המשתמש יכול להקיש על ההתראה כדי להתחיל את כוונת ההרשאה. השיחות יתווספו לתור ויבוצע ניסיון חוזר ברגע שההרשאה תינתן.