درخواست مجوزهای زمان اجرا

هر برنامه Android در جعبه ایمنی با دسترسی محدود اجرا می شود. اگر برنامه شما نیاز به استفاده از منابع یا اطلاعات خارج از جعبه ایمنی خود دارد، می توانید مجوز زمان اجرا را اعلام کنید و درخواست مجوزی را تنظیم کنید که این دسترسی را فراهم می کند. این مراحل بخشی از گردش کار برای استفاده از مجوزها هستند.

اگر مجوزهای خطرناکی را اعلام کردید، و اگر برنامه شما بر روی دستگاهی نصب شده است که دارای Android 6.0 (سطح API 23) یا بالاتر است، باید با دنبال کردن مراحل این راهنما، مجوزهای خطرناک را در زمان اجرا درخواست کنید.

اگر هیچ مجوز خطرناکی را اعلام نکنید، یا اگر برنامه شما روی دستگاهی نصب شده باشد که دارای Android نسخه 5.1 (سطح API 22) یا پایین‌تر است، مجوزها به‌طور خودکار اعطا می‌شوند و نیازی به انجام هیچ یک از مراحل باقی‌مانده نیست. در این صفحه

اصول اولیه

اصول اولیه درخواست مجوز در زمان اجرا به شرح زیر است:

  • هنگامی که کاربر شروع به تعامل با ویژگی مورد نیاز خود می کند، در زمینه درخواست مجوز کنید.
  • کاربر را مسدود نکنید همیشه گزینه لغو یک UI آموزشی را ارائه دهید، مانند جریانی که دلیل درخواست مجوزها را توضیح می دهد.
  • اگر کاربر مجوزی را که یک ویژگی به آن نیاز دارد رد یا لغو کرد، برنامه خود را به آرامی تنزل دهید تا کاربر بتواند به استفاده از برنامه شما ادامه دهد، احتمالاً با غیرفعال کردن ویژگی نیاز به مجوز.
  • هیچ رفتار سیستمی را فرض نکنید. به عنوان مثال، فرض نکنید که مجوزها در یک گروه مجوز ظاهر می شوند. یک گروه مجوز صرفاً به سیستم کمک می‌کند تا زمانی که یک برنامه مجوزهای مرتبط را درخواست می‌کند، تعداد گفتگوهای سیستمی را که به کاربر ارائه می‌شوند به حداقل برساند.

گردش کار برای درخواست مجوز

قبل از اعلام و درخواست مجوزهای زمان اجرا در برنامه خود، بررسی کنید که آیا برنامه شما نیاز به انجام این کار دارد یا خیر . شما می توانید بسیاری از موارد استفاده را در برنامه خود انجام دهید، مانند گرفتن عکس، توقف پخش رسانه، و نمایش تبلیغات مرتبط، بدون نیاز به اعلام هیچ مجوزی.

اگر به این نتیجه رسیدید که برنامه شما نیاز به اعلام و درخواست مجوزهای زمان اجرا دارد، این مراحل را کامل کنید:

  1. در فایل مانیفست برنامه خود، مجوزهایی را که ممکن است برنامه شما نیاز به درخواست داشته باشد، اعلام کنید .
  2. UX برنامه خود را طوری طراحی کنید که اقدامات خاص در برنامه شما با مجوزهای زمان اجرا خاصی مرتبط باشد. به کاربران اطلاع دهید که چه اقداماتی ممکن است به آنها نیاز داشته باشد تا به برنامه شما اجازه دسترسی به داده های کاربر خصوصی را بدهند.
  3. منتظر بمانید تا کاربر کار یا اقدامی را در برنامه شما فراخوانی کند که نیاز به دسترسی به داده های خصوصی کاربر خاص دارد. در آن زمان، برنامه شما می تواند مجوز زمان اجرا را که برای دسترسی به آن داده ها لازم است درخواست کند.
  4. بررسی کنید که آیا کاربر قبلاً مجوز زمان اجرا مورد نیاز برنامه شما را اعطا کرده است یا خیر . اگر چنین است، برنامه شما می تواند به داده های کاربر خصوصی دسترسی داشته باشد. اگر نه، به مرحله بعد ادامه دهید.

    هر بار که عملیاتی را انجام می دهید که به آن مجوز نیاز دارد، باید بررسی کنید که آیا مجوز دارید یا خیر.

  5. بررسی کنید که آیا برنامه شما باید منطقی را به کاربر نشان دهد و توضیح دهد که چرا برنامه شما به کاربر اجازه زمان اجرا خاصی را نیاز دارد. اگر سیستم تشخیص داد که برنامه شما نباید منطقی را نشان دهد، مستقیماً بدون نشان دادن عنصر UI به مرحله بعدی ادامه دهید.

    با این حال، اگر سیستم تشخیص دهد که برنامه شما باید منطقی را نشان دهد، منطق را در یک عنصر UI به کاربر ارائه دهید. در این منطق، به وضوح توضیح دهید که برنامه شما در حال تلاش برای دسترسی به چه داده‌هایی است و در صورت اعطای مجوز زمان اجرا، برنامه چه مزایایی می‌تواند به کاربر ارائه دهد. پس از اینکه کاربر دلیل منطقی را تأیید کرد، به مرحله بعدی ادامه دهید.

  6. مجوز زمان اجرا را که برنامه شما برای دسترسی به داده های خصوصی کاربر نیاز دارد، درخواست کنید . سیستم یک درخواست مجوز زمان اجرا را نمایش می دهد، مانند آنچه در صفحه نمای کلی مجوزها نشان داده شده است.

  7. پاسخ کاربر را بررسی کنید – اینکه آیا او اجازه زمان اجرا را اعطا کرده یا رد کرده است.

  8. اگر کاربر به برنامه شما مجوز داده است، می توانید به داده های کاربر خصوصی دسترسی داشته باشید. اگر کاربر به جای آن مجوز را رد کرد، تجربه برنامه خود را به‌خوبی کاهش دهید تا بدون اطلاعاتی که توسط آن مجوز محافظت می‌شود، عملکردی را در اختیار کاربر قرار دهد.

شکل 1 گردش کار و مجموعه تصمیمات مرتبط با این فرآیند را نشان می دهد:

شکل 1. نموداری که گردش کار را برای اعلام و درخواست مجوزهای زمان اجرا در اندروید نشان می دهد.

تعیین کنید که آیا برنامه شما قبلاً مجوز داده است یا خیر

برای بررسی اینکه آیا کاربر قبلاً مجوز خاصی را به برنامه شما اعطا کرده است یا خیر، آن مجوز را به روش ContextCompat.checkSelfPermission() بدهید. این روش بسته به اینکه برنامه شما مجوز را داشته باشد، PERMISSION_GRANTED یا PERMISSION_DENIED را برمی‌گرداند.

توضیح دهید که چرا برنامه شما به مجوز نیاز دارد

هنگام فراخوانی requestPermissions() توسط سیستم نشان داده می‌شود، می‌گوید برنامه شما چه مجوزی می‌خواهد، اما دلیل آن را نمی‌گوید. در برخی موارد، کاربر ممکن است آن را گیج کننده بداند. بهتر است قبل از فراخوانی requestPermissions() به کاربر توضیح دهید که چرا برنامه شما مجوزها را می خواهد.

تحقیقات نشان می‌دهد که کاربران با درخواست‌های مجوز بسیار راحت‌تر هستند، اگر بدانند چرا برنامه به آنها نیاز دارد، مانند اینکه آیا مجوز برای پشتیبانی از ویژگی اصلی برنامه یا برای تبلیغات لازم است. در نتیجه، اگر فقط از بخشی از تماس‌های API استفاده می‌کنید که تحت یک گروه مجوز قرار می‌گیرند، فهرست کردن صریح از کدام یک از آن مجوزها و دلیل استفاده از آن کمک می‌کند. به عنوان مثال، اگر فقط از موقعیت مکانی درشت استفاده می کنید، این را در توضیحات برنامه خود یا در مقاله های راهنمای برنامه خود به کاربر اطلاع دهید.

تحت شرایط خاص، اطلاع رسانی به کاربران در مورد دسترسی به داده های حساس در زمان واقعی نیز مفید است. برای مثال، اگر به دوربین یا میکروفون دسترسی دارید، بهتر است با استفاده از نماد اعلان در جایی از برنامه خود یا در سینی اعلان (اگر برنامه در پس‌زمینه اجرا می‌شود) به کاربر اطلاع دهید. به نظر نمی رسد که شما به طور مخفیانه داده ها را جمع آوری می کنید.

در نهایت، اگر برای فعال کردن چیزی در برنامه خود نیاز به درخواست مجوز دارید، اما دلیل آن برای کاربر روشن نیست، راهی پیدا کنید تا به کاربر اطلاع دهید که چرا به حساس ترین مجوزها نیاز دارید.

اگر متد ContextCompat.checkSelfPermission() PERMISSION_DENIED را برمی گرداند، shouldShowRequestPermissionRationale() را فراخوانی کنید. اگر این روش true را برگرداند، یک رابط کاربری آموزشی به کاربر نشان دهید. در این رابط کاربری، توضیح دهید که چرا ویژگی که کاربر می‌خواهد فعال کند به مجوز خاصی نیاز دارد.

بعلاوه، اگر برنامه شما مجوز مربوط به مکان، میکروفون یا دوربین را درخواست کرد، توضیح دهید که چرا برنامه شما به این اطلاعات نیاز دارد .

درخواست مجوزها

پس از اینکه کاربر یک UI آموزشی را مشاهده کرد، یا مقدار بازگشتی shouldShowRequestPermissionRationale() نشان داد که نیازی به نشان دادن یک رابط کاربری آموزشی ندارید، اجازه درخواست کنید. کاربران یک گفتگوی مجوز سیستم را می بینند، جایی که می توانند انتخاب کنند که آیا مجوز خاصی را به برنامه شما اعطا کنند یا خیر.

برای انجام این کار، از قرارداد RequestPermission ، موجود در کتابخانه AndroidX استفاده کنید، جایی که به سیستم اجازه می دهید کد درخواست مجوز را برای شما مدیریت کند . از آنجا که استفاده از قرارداد RequestPermission منطق شما را ساده می کند، در صورت امکان راه حل پیشنهادی است. با این حال، در صورت نیاز، می‌توانید یک کد درخواست را خودتان نیز به عنوان بخشی از درخواست مجوز مدیریت کنید و این کد درخواست را در منطق پاسخ تماس مجوز خود قرار دهید.

به سیستم اجازه دهید کد درخواست مجوز را مدیریت کند

برای اینکه به سیستم اجازه دهید کد درخواست مرتبط با درخواست مجوز را مدیریت کند، وابستگی هایی را به کتابخانه های زیر در فایل build.gradle ماژول خود اضافه کنید:

سپس می توانید از یکی از کلاس های زیر استفاده کنید:

  • برای درخواست یک مجوز، از RequestPermission استفاده کنید.
  • برای درخواست چندین مجوز به طور همزمان، از RequestMultiplePermissions استفاده کنید.

مراحل زیر نحوه استفاده از قرارداد RequestPermission را نشان می دهد. این فرآیند برای قرارداد RequestMultiplePermissions تقریباً یکسان است.

  1. در منطق اولیه سازی اکتیویتی یا قطعه خود، پیاده سازی ActivityResultCallback را به یک فراخوانی به registerForActivityResult() منتقل کنید. ActivityResultCallback نحوه برخورد برنامه شما با پاسخ کاربر به درخواست مجوز را مشخص می کند.

    یک مرجع به مقدار بازگشتی registerForActivityResult() که از نوع ActivityResultLauncher است، نگه دارید.

  2. برای نمایش دیالوگ مجوزهای سیستم در صورت لزوم، متد launch() را در نمونه ActivityResultLauncher که در مرحله قبل ذخیره کردید فراخوانی کنید.

    پس از launch() ، کادر محاوره مجوزهای سیستم ظاهر می شود. هنگامی که کاربر انتخابی انجام می دهد، سیستم به طور ناهمزمان اجرای ActivityResultCallback را که در مرحله قبل تعریف کردید، فراخوانی می کند.

    توجه: برنامه شما نمی‌تواند گفتگویی را که هنگام فراخوانی launch() ظاهر می‌شود، سفارشی کند. برای ارائه اطلاعات یا زمینه بیشتر به کاربر، رابط کاربری برنامه خود را تغییر دهید تا درک اینکه چرا یک ویژگی در برنامه شما به مجوز خاصی نیاز دارد برای کاربران آسان تر باشد. به عنوان مثال، می توانید متن را در دکمه ای که این ویژگی را فعال می کند تغییر دهید.

    همچنین، متن در گفتگوی مجوز سیستم به گروه مجوز مرتبط با مجوزی که درخواست کرده‌اید اشاره می‌کند. این گروه‌بندی مجوز برای سهولت استفاده از سیستم طراحی شده است و برنامه شما نباید به مجوزهایی که در داخل یا خارج از یک گروه مجوز خاص هستند متکی باشد.

قطعه کد زیر نحوه رسیدگی به پاسخ مجوزها را نشان می دهد:

کاتلین

// 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.
        }
    }

جاوا

// 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.
        }
    });

و این قطعه کد فرآیند توصیه شده برای بررسی مجوز و درخواست مجوز از کاربر در صورت لزوم را نشان می دهد:

کاتلین

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)
    }
}

جاوا

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);
}

کد درخواست مجوز را خودتان مدیریت کنید

به عنوان جایگزینی برای اجازه دادن به سیستم برای مدیریت کد درخواست مجوز ، می‌توانید کد درخواست مجوز را خودتان مدیریت کنید. برای انجام این کار، کد درخواست را در یک فراخوانی به requestPermissions() قرار دهید.

قطعه کد زیر نحوه درخواست مجوز با استفاده از کد درخواست را نشان می دهد:

کاتلین

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)
    }
}

جاوا

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() را فراخوانی می کند. سیستم در پاسخ کاربر به گفتگوی مجوز و همچنین کد درخواستی که شما تعریف کرده‌اید، همانطور که در قطعه کد زیر نشان داده شده است، ارسال می‌کند:

کاتلین

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.
        }
    }
}

جاوا

@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.
    }
}

درخواست مجوزهای مکان

وقتی مجوزهای مکان را درخواست می‌کنید، بهترین روش‌ها را مانند هر مجوز زمان اجرا دیگری دنبال کنید. یک تفاوت مهم در مورد مجوزهای مکان این است که سیستم شامل چندین مجوز مربوط به مکان است. مجوزهایی که درخواست می‌کنید و نحوه درخواست آن‌ها به شرایط مکانی مورد نیاز برنامه شما بستگی دارد.

موقعیت پیش زمینه

اگر برنامه شما دارای ویژگی است که اطلاعات مکان را فقط یک بار یا برای مدت زمان مشخصی به اشتراک می گذارد یا دریافت می کند، آن ویژگی به دسترسی به موقعیت مکانی پیش زمینه نیاز دارد. برخی از نمونه ها شامل موارد زیر است:

  • در یک برنامه ناوبری، یک ویژگی به کاربران امکان می دهد مسیرهای گام به گام را دریافت کنند.
  • در یک برنامه پیام رسانی، یک ویژگی به کاربران امکان می دهد مکان فعلی خود را با کاربر دیگری به اشتراک بگذارند.

اگر یکی از ویژگی‌های برنامه شما در یکی از شرایط زیر به مکان فعلی دستگاه دسترسی پیدا کند، سیستم برنامه شما را به‌عنوان از مکان پیش‌زمینه استفاده می‌کند:

  • فعالیتی که به برنامه شما تعلق دارد قابل مشاهده است.
  • برنامه شما در حال اجرای یک سرویس پیش زمینه است. هنگامی که یک سرویس پیش زمینه در حال اجرا است، سیستم با نشان دادن یک اعلان مداوم، آگاهی کاربر را افزایش می دهد. وقتی برنامه شما در پس‌زمینه قرار می‌گیرد، مانند زمانی که کاربر دکمه Home را روی دستگاهش فشار می‌دهد یا نمایشگر دستگاهش را خاموش می‌کند، دسترسی خود را حفظ می‌کند.

    در Android 10 (سطح API 29) و بالاتر، باید نوع location مکانی سرویس پیش زمینه را اعلام کنید، همانطور که در قطعه کد زیر نشان داده شده است. در نسخه های قبلی اندروید، توصیه می شود این نوع سرویس پیش زمینه را اعلام کنید.

    <!-- 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>

موقعیت مکانی پس زمینه

اگر یک ویژگی در برنامه دائماً مکان را با سایر کاربران به اشتراک می‌گذارد یا از Geofencing API استفاده می‌کند، یک برنامه نیاز به دسترسی به موقعیت مکانی پس‌زمینه دارد. چندین مثال شامل موارد زیر است:

  • در یک برنامه اشتراک‌گذاری موقعیت مکانی خانوادگی، یک ویژگی به کاربران امکان می‌دهد به طور مداوم مکان را با اعضای خانواده به اشتراک بگذارند.
  • در یک برنامه اینترنت اشیا، یک ویژگی به کاربران امکان می‌دهد دستگاه‌های خانگی خود را به گونه‌ای پیکربندی کنند که وقتی کاربر خانه خود را ترک می‌کند، خاموش می‌شوند و وقتی کاربر به خانه بازگشت دوباره روشن می‌شوند.

اگر برنامه شما در هر موقعیتی غیر از مواردی که در قسمت موقعیت پیش‌زمینه توضیح داده شده است به مکان فعلی دستگاه دسترسی پیدا کند، سیستم در نظر می‌گیرد که از موقعیت مکانی پس‌زمینه استفاده می‌کند. دقت موقعیت مکانی پس‌زمینه مانند دقت موقعیت مکانی پیش‌زمینه است که به مجوزهای مکانی که برنامه شما اعلام می‌کند بستگی دارد.

در Android 10 (سطح API 29) و بالاتر، برای درخواست دسترسی به موقعیت مکانی پس‌زمینه در زمان اجرا، باید مجوز ACCESS_BACKGROUND_LOCATION را در مانیفست برنامه خود اعلام کنید. در نسخه های قبلی اندروید، زمانی که برنامه شما به موقعیت مکانی پیش زمینه دسترسی پیدا می کند، به طور خودکار به موقعیت مکانی پس زمینه نیز دسترسی پیدا می کند.

<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، از صفحه مرجع API مجوزها دیدن کنید.

مجوزهای یکبار مصرف

گزینه ای به نام "فقط این بار" دومین دکمه از سه دکمه در گفتگو است.
شکل 2. محاوره سیستم که زمانی ظاهر می شود که یک برنامه یک مجوز یک بار درخواست می کند.

با شروع در Android 11 (سطح API 30)، هر زمان که برنامه شما مجوز مربوط به مکان، میکروفون یا دوربین را درخواست کند، کادر گفتگوی مجوزهای رو به روی کاربر حاوی گزینه ای به نام فقط این بار است، همانطور که در شکل 2 نشان داده شده است. اگر کاربر این مورد را انتخاب کند. گزینه در گفتگو، به برنامه شما یک مجوز موقت یک بار اعطا می شود.

سپس برنامه شما می‌تواند برای مدتی به داده‌های مرتبط دسترسی داشته باشد که به رفتار برنامه و اقدامات کاربر بستگی دارد:

  • در حالی که فعالیت برنامه شما قابل مشاهده است، برنامه شما می تواند به داده ها دسترسی داشته باشد.
  • اگر کاربر برنامه شما را به پس‌زمینه ارسال کند، برنامه شما می‌تواند برای مدت کوتاهی به داده‌ها دسترسی داشته باشد.
  • اگر سرویس پیش‌زمینه را راه‌اندازی کنید در حالی که فعالیت قابل مشاهده است، و سپس کاربر برنامه شما را به پس‌زمینه منتقل کند، برنامه شما می‌تواند به دسترسی به داده‌ها ادامه دهد تا زمانی که سرویس پیش‌زمینه متوقف شود.

با لغو مجوز، فرآیند برنامه خاتمه می یابد

اگر کاربر مجوز یکبار مصرف را لغو کند، مانند تنظیمات سیستم، برنامه شما نمی‌تواند به داده‌ها دسترسی داشته باشد، صرف نظر از اینکه سرویس پیش‌زمینه را راه‌اندازی کرده‌اید یا خیر. مانند هر مجوز دیگری، اگر کاربر مجوز یکبار مصرف برنامه شما را لغو کند، روند برنامه شما خاتمه می یابد.

هنگامی که کاربر در مرحله بعدی برنامه شما را باز می کند و یکی از ویژگی های برنامه شما درخواست دسترسی به مکان، میکروفون یا دوربین را می دهد، دوباره از کاربر درخواست می شود که مجوز دریافت کند.

بازنشانی مجوزهای استفاده نشده

Android راه‌های مختلفی برای بازنشانی مجوزهای زمان اجرا استفاده نشده به حالت پیش‌فرض و رد شده ارائه می‌کند:

دسترسی برنامه را حذف کنید

در Android 13 (سطح API 33) و بالاتر، می‌توانید دسترسی برنامه‌تان به مجوزهای زمان اجرا را که برنامه شما دیگر به آن نیاز ندارد حذف کنید. وقتی برنامه خود را به روز می کنید، این مرحله را انجام دهید تا کاربران بیشتر متوجه شوند که چرا برنامه شما همچنان به درخواست مجوزهای خاص ادامه می دهد. این دانش به ایجاد اعتماد کاربر در برنامه شما کمک می کند.

برای حذف دسترسی به مجوز زمان اجرا، نام آن مجوز را به revokeSelfPermissionOnKill() ارسال کنید. برای حذف دسترسی به گروهی از مجوزهای زمان اجرا به طور همزمان، مجموعه ای از نام مجوزها را به revokeSelfPermissionsOnKill() ارسال کنید. فرآیند حذف مجوز به صورت ناهمزمان انجام می شود و تمام فرآیندهای مرتبط با UID برنامه شما را از بین می برد.

برای اینکه سیستم دسترسی برنامه شما به مجوزها را حذف کند، تمام فرآیندهای مرتبط با برنامه شما باید از بین بروند. هنگامی که شما با API تماس می گیرید، سیستم تعیین می کند که از بین بردن این فرآیندها چه زمانی ایمن است. معمولاً سیستم منتظر می ماند تا برنامه شما مدت زمان طولانی را به جای پیش زمینه در پس زمینه اجرا کند.

برای اطلاع دادن به کاربر مبنی بر اینکه برنامه شما دیگر نیازی به دسترسی به مجوزهای زمان اجرا خاصی ندارد، دفعه بعد که کاربر برنامه شما را راه اندازی کرد، یک گفتگو را نشان دهید. این گفتگو می تواند شامل لیستی از مجوزها باشد.

بازنشانی خودکار مجوزهای برنامه های استفاده نشده

اگر برنامه شما Android 11 (سطح API 30) یا بالاتر را هدف قرار می دهد و برای چند ماه استفاده نمی شود، سیستم با بازنشانی خودکار مجوزهای زمان اجرا حساسی که کاربر به برنامه شما داده است، از داده های کاربر محافظت می کند. در راهنمای مربوط به خواب زمستانی برنامه بیشتر بیاموزید.

در صورت لزوم، درخواست کنید تا به کنترل کننده پیش فرض تبدیل شوید

برخی از برنامه ها به دسترسی به اطلاعات حساس کاربر مربوط به گزارش تماس ها و پیام های SMS بستگی دارند. اگر می‌خواهید مجوزهای مربوط به گزارش تماس‌ها و پیام‌های SMS را درخواست کنید و برنامه خود را در Play Store منتشر کنید، باید از کاربر بخواهید که برنامه شما را به عنوان کنترل‌کننده پیش‌فرض برای یک عملکرد سیستم اصلی قبل از درخواست این مجوزهای زمان اجرا تنظیم کند.

برای اطلاعات بیشتر در مورد کنترل‌کننده‌های پیش‌فرض، از جمله راهنمایی در مورد نمایش فرمان پیش‌فرض به کاربران، به راهنمای مجوزهایی که فقط در کنترل‌کننده‌های پیش‌فرض استفاده می‌شوند، مراجعه کنید .

همه مجوزهای زمان اجرا را برای اهداف آزمایشی اعطا کنید

برای اعطای خودکار تمام مجوزهای زمان اجرا هنگام نصب برنامه بر روی یک شبیه ساز یا دستگاه آزمایشی، همانطور که در قطعه کد زیر نشان داده شده است، از گزینه -g برای دستور adb shell install استفاده کنید:

adb shell install -g PATH_TO_APK_FILE

منابع اضافی

برای اطلاعات بیشتر در مورد مجوزها، این مقالات را بخوانید:

برای کسب اطلاعات بیشتر در مورد درخواست مجوز، نمونه مجوزها را مرور کنید

همچنین می‌توانید این کد را تکمیل کنید که بهترین شیوه‌های حفظ حریم خصوصی را نشان می‌دهد .