בקשת הרשאות בזמן ריצה

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

אם אתם מצהירים על סכנה , ואם האפליקציה מותקנת במכשיר שבו פועלת Android 6.0 (רמת API 23) או עליכם לבקש את ההרשאות המסוכנות בזמן הריצה: במדריך הזה.

אם לא הצהרתם על הרשאות מסוכנות, או אם האפליקציה שלכם מותקנת במכשיר שפועלת בו גרסת Android 5.1 (רמת API 22) ומטה, ההרשאות מוענקות אוטומטית, ואין צורך להשלים את השלבים הנותרים בדף הזה.

עקרונות בסיסיים

אלה העקרונות הבסיסיים לבקשת הרשאות בזמן ריצה:

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

תהליך עבודה לבקשת הרשאות

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

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

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

    עליך לבדוק אם יש לך הרשאה בכל פעם שאתה מבצע פעולה שדורשת את ההרשאה הזו.

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

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

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

  7. לבדוק את תגובת המשתמש — האם הוא בחר לאשר או לדחות את הרשאה בתחילת ההפעלה.

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

איור 1 ממחיש את תהליך העבודה ואת קבוצת ההחלטות שמשויכות אליו תהליך:

איור 1. תרשים שמראה את תהליך העבודה להצהרה בקשת הרשאות בתחילת ההפעלה ב-Android.

איך לבדוק אם האפליקציה כבר קיבלה את ההרשאה

כדי לבדוק אם המשתמש כבר העניק לאפליקציה שלכם הרשאה מסוימת, מעבירים את ההרשאה הזו ContextCompat.checkSelfPermission() . השיטה הזו מחזירה PERMISSION_GRANTED או PERMISSION_DENIED, בהתאם להרשאה של האפליקציה.

צריך להסביר למה לאפליקציה שלך נדרשת הרשאה

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

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

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

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

אם ה-method ContextCompat.checkSelfPermission() מחזירה PERMISSION_DENIED, להתקשר אל shouldShowRequestPermissionRationale(). אם השיטה הזו מחזירה את הערך true, צריך להציג למשתמש ממשק משתמש חינוכי. בממשק המשתמש הזה, תיאור של הסיבה לכך שהמשתמש רוצה להפעיל הרשאה.

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

בקשת הרשאות

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

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

מתן הרשאה למערכת לנהל את הקוד של בקשת ההרשאה

כדי לאפשר למערכת לנהל את קוד הבקשה שמשויך אל הרשאות ספציפיות, הוסיפו יחסי תלות בספריות הבאות קובץ build.gradle של המודול:

לאחר מכן אפשר להשתמש באחת מהמחלקות הבאות:

בשלבים הבאים מוסבר איך להשתמש בחוזה RequestPermission. התהליך כמעט זהה בחוזה RequestMultiplePermissions.

  1. בלוגיקת האתחול של הפעילות או המקטע, מעבירים הטמעה מתוך ActivityResultCallback לשיחה registerForActivityResult() בActivityResultCallback מוגדר האופן שבו האפליקציה תטפל בתגובת המשתמש בקשת ההרשאה.

    מומלץ לשמור הפניה לערך המוחזר של registerForActivityResult(), הוא מסוג ActivityResultLauncher.

  2. כדי להציג את תיבת הדו-שיח להרשאות המערכת במקרה הצורך, קוראים launch() במופע של ActivityResultLauncher ששמרת ב לשלב הקודם.

    אחרי הקריאה ל-launch(), תופיע תיבת הדו-שיח להרשאות המערכת. כאשר שהמשתמש בוחר, המערכת מפעילה את ההטמעה באופן אסינכרוני של ActivityResultCallback, שהגדרת בשלב הקודם.

    הערה: באפליקציה אי אפשר להתאים אישית את תיבת הדו-שיח שמופיעה כשמתקשרים אל launch(). כדי לספק מידע נוסף או של המשתמש, לשנות את ממשק המשתמש של האפליקציה כדי שלמשתמשים יהיה קל יותר להבין למה נדרשת הרשאה מסוימת לתכונה באפליקציה. עבור לדוגמה, אפשר לשנות את הטקסט בלחצן שמפעיל את .

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

קטע הקוד הבא מראה איך לטפל בתגובת ההרשאות:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your
            // app.
        } else {
            // Explain to the user that the feature is unavailable because the
            // feature requires a permission that the user has denied. At the
            // same time, respect the user's decision. Don't link to system
            // settings in an effort to convince the user to change their
            // decision.
        }
    });

וקטע הקוד מדגים את התהליך המומלץ לבדיקה הרשאה ולבקש הרשאה מהמשתמש במקרה הצורך:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        // The registered ActivityResultCallback gets the result of this request.
        requestPermissionLauncher.launch(
                Manifest.permission.REQUESTED_PERMISSION)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    // The registered ActivityResultCallback gets the result of this request.
    requestPermissionLauncher.launch(
            Manifest.permission.REQUESTED_PERMISSION);
}

ניהול הקוד של בקשת ההרשאה בעצמכם

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

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

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
        performAction(...)
    }
    ActivityCompat.shouldShowRequestPermissionRationale(
            this, Manifest.permission.REQUESTED_PERMISSION) -> {
        // In an educational UI, explain to the user why your app requires this
        // permission for a specific feature to behave as expected, and what
        // features are disabled if it's declined. In this UI, include a
        // "cancel" or "no thanks" button that lets the user continue
        // using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // You can directly ask for the permission.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.REQUESTED_PERMISSION),
                REQUEST_CODE)
    }
}

Java

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.REQUESTED_PERMISSION) ==
        PackageManager.PERMISSION_GRANTED) {
    // You can use the API that requires the permission.
    performAction(...);
} else if (ActivityCompat.shouldShowRequestPermissionRationale(
        this, Manifest.permission.REQUESTED_PERMISSION)) {
    // In an educational UI, explain to the user why your app requires this
    // permission for a specific feature to behave as expected, and what
    // features are disabled if it's declined. In this UI, include a
    // "cancel" or "no thanks" button that lets the user continue
    // using your app without granting the permission.
    showInContextUI(...);
} else {
    // You can directly ask for the permission.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.REQUESTED_PERMISSION },
            REQUEST_CODE);
}

אחרי שהמשתמש מגיב לתיבת הדו-שיח של הרשאות המערכת, מפעיל את היישום של onRequestPermissionsResult() באפליקציה. המערכת מעבירה את המשתמש לתיבת הדו-שיח של ההרשאה וגם לקוד הבקשה שהגדרתם, כפי שמוצג בקטע הקוד הבא:

Kotlin

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            } else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return
        }

        // Add other 'when' lines to check for other
        // permissions this app might request.
        else -> {
            // Ignore all other requests.
        }
    }
}

Java

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
            }  else {
                // Explain to the user that the feature is unavailable because
                // the feature requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
            }
            return;
        }
        // Other 'case' lines to check for other
        // permissions this app might request.
    }
}

שליחת בקשה להרשאות מיקום

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

מיקום בחזית

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

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

המערכת מחשיבה את האפליקציה לשימוש במיקום בחזית אם תכונה של האפליקציה שלך ניגשת למיקום הנוכחי של המכשיר באחת מהאפשרויות הבאות מצבים:

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

    ב-Android מגרסה 10 (API ברמה 29) ואילך, צריך להצהיר על קדמת הבמה סוג השירות של location, כפי שמוצג בקטע הקוד הבא. בגרסאות קודמות של Android, מומלץ להצהיר על סוג השירות שפועל בחזית.

    <!-- Recommended for Android 9 (API level 28) and lower. -->
    <!-- Required for Android 10 (API level 29) and higher. -->
    <service
        android:name="MyNavigationService"
        android:foregroundServiceType="location" ... >
        <!-- Any inner elements go here. -->
    </service>
    

את/ה מצהיר/ה על הצורך במיקום בחזית כשהאפליקציה מבקשת ACCESS_COARSE_LOCATION או את ACCESS_FINE_LOCATION הרשאה, כפי שמוצג בקטע הקוד הבא:

<manifest ... >
  <!-- Include this permission any time your app needs location information. -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

  <!-- Include only if your app benefits from precise location access. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

מיקום ברקע

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

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

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

ב-Android מגרסה 10 (API ברמה 29) ואילך, צריך להצהיר על ACCESS_BACKGROUND_LOCATION הרשאה במניפסט של האפליקציה לבקש מיקום ברקע גישה בזמן ריצה. בגרסאות קודמות של ב-Android, כשהאפליקציה מקבלת גישה למיקום בחזית, היא מתבצעת באופן אוטומטי מקבל גם גישה למיקום ברקע.

<manifest ... >
  <!-- Required only when requesting background location access on
       Android 10 (API level 29) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

איך מטפלים בדחיית ההרשאות

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

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

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

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

במקביל, האפליקציה צריכה לפעול בהתאם להחלטת המשתמש לדחות מודעה הרשאה. החל מ-Android 11 (רמת API 30), אם המשתמש מקיש על דחייה לצורך הרשאה ספציפית יותר מפעם אחת במהלך כל משך ההתקנה של האפליקציה במכשיר, המשתמש לא רואה את תיבת הדו-שיח להרשאות המערכת אם האפליקציה יבקש את ההרשאה הזו שוב. מפעולת המשתמש משתמע "לא לשאול שוב". במצב מופעל בעבר, המשתמשים ראו את תיבת הדו-שיח של הרשאות המערכת בכל פעם אפליקציה ביקשה הרשאה, אלא אם היא בחרה בעבר תיבת דו-שיח "לא לשאול" שוב" תיבת סימון או אפשרות.

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

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

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

בדיקת סטטוס הדחייה במהלך בדיקה וניפוי באגים

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

adb shell dumpsys package PACKAGE_NAME

כאשר PACKAGE_NAME הוא שם החבילה שרוצים לבדוק.

הפלט של הפקודה מכיל קטעים שנראים כך:

...
runtime permissions:
  android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SET|USER_FIXED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
  android.permission.BLUETOOTH_CONNECT: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED]
...

הרשאות שנדחו על ידי המשתמש פעם אחת מסומנות על ידי USER_SET. הרשאות שנדחו באופן סופי על ידי בחירה באפשרות דחייה הן פעמיים סומן על ידי USER_FIXED.

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

adb shell pm clear-permission-flags PACKAGE_NAME PERMISSION_NAME user-set user-fixed

PERMISSION_NAME הוא שם ההרשאה שרוצים לקבל לאתחל.

כדי להציג רשימה מלאה של ההרשאות הניתנות לאפליקציה ל-Android, אפשר לעבור לקישור הבא: Permissions API דף עזר.

הרשאות חד-פעמיות

האפשרות &#39;רק הפעם&#39; הוא הלחצן השני מתוך שלושה
    תיבת הדו-שיח.
איור 2. תיבת דו-שיח של המערכת שמופיעה כשנשלחת בקשה מאפליקציה הרשאה חד-פעמית.

החל מ-Android 11 (רמת API 30), בכל פעם שהאפליקציה מבקשת הרשאה שקשורים למיקום, למיקרופון או למצלמה, בתיבת הדו-שיח להרשאות שגלויות למשתמש כולל אפשרות שנקראת רק הפעם, כפי שמוצג באיור 2. אם המשתמש בוחר באפשרות הזאת בתיבת הדו-שיח, האפליקציה שלכם קיבלה הרשאה חד-פעמית זמנית.

לאחר מכן האפליקציה יכולה לגשת לנתונים הקשורים למשך פרק זמן תלוי: התנהגות האפליקציה ופעולות המשתמשים:

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

תהליך האפליקציה מסתיים כשההרשאה מבוטלת

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

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

איפוס הרשאות שלא נמצאות בשימוש

ב-Android יש כמה דרכים לאפס הרשאות בזמן ריצה שלא נמצאות בשימוש ברירת מחדל, מצב נדחה:

הסרת הגישה לאפליקציות

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

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

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

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

איפוס אוטומטי של הרשאות לאפליקציות שלא בשימוש

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

אם צריך, מבקשים להפוך ל-handler שמוגדר כברירת מחדל

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

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

הקצאת כל ההרשאות בסביבת זמן הריצה למטרות בדיקה

כדי להעניק את כל ההרשאות בזמן הריצה באופן אוטומטי כשמתקינים אפליקציה אמולטור או מכשיר בדיקה, צריך להשתמש באפשרות -g עבור adb shell install של הפקודה, כפי שמוצג בקטע הקוד הבא:

adb shell install -g PATH_TO_APK_FILE

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

במאמרים הבאים אפשר למצוא מידע נוסף על הרשאות:

כדי לקבל מידע נוסף על בקשת הרשאות, אפשר לעיין ב דוגמאות להרשאות

אפשר גם להשלים את ה-Codelab הזה שמדגים את הפרטיות הכי טובה שיטות.