החל מ-Android 6.0 Marshmallow, מערכת Android משתמשת מודל הרשאות שמייעל את התקנת האפליקציה תהליך העדכון האוטומטי. ההרשאות מבוקשות בזמן הריצה במקום בעבר התקנת האפליקציה. בנוסף, המשתמשים יכולים לבחור לדחות הרשאות מסוימות. כדי להעניק למשתמשים את הגמישות הזו, צריך לוודא שהאפליקציה פועלת בהתאם לצפות כאשר משתמש מפעיל או משבית הרשאה מסוימת.
ל-Google Play Services יש הרשאות בתחילת ההפעלה שהמשתמשים יכולים לבחור לדחות בנפרד מההרשאות שהתבקשו באופן ספציפי על ידי תרגום מכונה. Google Play Services מקבלת באופן אוטומטי את כל ההרשאות הנדרשות כדי לתמוך בממשקי ה-API שלו. עם זאת, האפליקציה עדיין צריכה לבדוק ולבקש את זמן הריצה הרשאות לפי הצורך ולטפל בשגיאות כראוי במקרים שבהם סרב ל-Google Play Services הרשאה שנדרשת ל-API שהאפליקציה שלך משתמשת בו.
מומלץ לנהל את ציפיות המשתמש כשמגדירים הרשאות יכול להיות שיידרש. השיטות המומלצות הבאות יעזרו לכם להימנע של בעיות פוטנציאליות.
דרישות מוקדמות
עליך להצהיר על ההרשאות בקובץ AndroidManifest.xml
.
לדוגמה:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
הנחיות
אימות ההרשאות לפני קריאה לממשקי API
אחרי שהצהרת על ממשקי ה-API שברצונך להשתמש בהם
AndroidManifest.xml
, צריך לוודא שיש לך את ההרשאה הנדרשת
לפני קריאה ל-API. אפשר לעשות זאת באמצעות השיטה checkSelfPermission
.
מתוך ActivityCompat
או ContextCompat
.
אם הקריאה מחזירה False, המשמעות היא שההרשאות לא הוענקו
צריך להשתמש ב-requestPermissions
כדי לבקש אותם. התשובה לכך היא
הוחזרה בקריאה חוזרת (callback) שתוצג בשלב הבא.
לדוגמה:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
// permission has been granted, continue as usual
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
}
הטמעת הקריאה החוזרת של הבקשה להרשאה
אם ההרשאה שנדרשת לאפליקציה לא ניתנה על ידי המשתמש,
צריך להפעיל את השיטה requestPermissions
כדי לשאול את השיטה
המשתמש כדי להעניק להם גישה. התגובה של המשתמש מתועדת
onRequestPermissionsResult
קריאה חוזרת (callback). האפליקציה שלך צריכה
תטמיעו את זה ותבדקו תמיד את הערכים המוחזרים, כי הבקשה יכולה להיות
נדחתה או בוטלה. אפשר גם לבקש מספר הרשאות ולבדוק אותן בכתובת
בדוגמה הבאה בודקים אם יש הרשאה יחידה בלבד.
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_LOCATION) {
if(grantResults.length == 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// We can now safely use the API we requested access to
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
} else {
// Permission was denied or request was cancelled
}
}
}
הצגת הנימוקים להרשאה
אם ההרשאות שהאפליקציה מבקשת נחוצות לתכונות העיקריות של והמשתמש דחה בעבר את בקשת ההרשאה, האפליקציה שלך להציג הסבר נוסף לפני בקשת ההרשאה שוב. משתמשים מעניקים הרשאות רבות יותר כאשר הם מבינים את הסיבה לכך את הצורך ולהגדיל את התועלת המיידית שלהם.
במקרה כזה, לפני השיחה אל requestPermissions
, צריך להתקשר
shouldShowRequestPermissionRationale
. אם הוא מוחזר
צריך ליצור ממשק משתמש כלשהו כדי להציג הקשר נוסף
הרשאה.
לדוגמה, הקוד עשוי להיראות כך:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
private static final int REQUEST_LOCATION = 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},
ACCESS_FINE_LOCATION);
}
} else {
// permission has been granted, continue as usual
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
}
טיפול בכשלים בחיבור
אם באפליקציה נעשה שימוש ברכיב GoogleApiClient
שהוצא משימוש, במהלך התקשרות
connect()
, פלטפורמת Google Play Services מוודאת שיש לה את כל
בהרשאות הנדרשות. הפעולה connect()
תיכשל אם יש קבוצות הרשאות
שנחוצים ל-Google Play Services עצמם.
אם הקריאה ל-connect()
תיכשל, צריך לוודא שהאפליקציה מטפלת
החיבור נכשל בצורה תקינה. אם Google Play Services
בעצמו חסרות הרשאות, אפשר להפעיל את startResolutionForResult()
כדי
להפעיל את התהליך למשתמש כדי לתקן את הבעיות.
לדוגמה:
@Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
בקריאות חדשות יותר ל-API המבוססות על GoogleApi
תוצג באופן אוטומטי תיבת דו-שיח (אם
נוצר על ידי הלקוח באמצעות Activity
) או התראה במגש המערכת (אם
הלקוח יוצר מופע של Context
) שהמשתמש יכול להקיש עליו כדי להפעיל את
Intent לפתרון הרשאות. השיחות יועברו לתור ויישלחו שוב לאחר
מוענקת הרשאה.