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

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

دستورالعمل‌های دسترسی به اجازه‌های مکان

برخی‌از قوانین کلی که باید هنگام تصمیم‌گیری درباره نحوه پیاده‌سازی دسترسی به مکان در برنامه‌تان رعایت کنید.

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

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

شکل ۱ نحوه انجام این فرایند را نشان می‌دهد. برنامه حاوی ویژگی «هم‌رسانی مکان» است که به دسترسی به مکان در پیش‌زمینه نیاز دارد. بااین‌حال، تا زمانی که کاربر دکمه هم‌رسانی مکان را انتخاب نکند، برنامه اجازه مکان را درخواست نمی‌کند.

پس‌از اینکه کاربر دکمه «هم‌رسانی مکان» را انتخاب می‌کند،
    کادر گفتگوی اجازه مکان سیستم ظاهر می‌شود
شکل ۱. ویژگی هم‌رسانی مکان که به دسترسی به مکان در پیش‌زمینه نیاز دارد. اگر کاربر فقط موقع استفاده از این برنامه اجازه داده شود را انتخاب کند، این ویژگی فعال می‌شود.

کاربر فقط می‌تواند مکان تقریبی را اعطا کند

در Android 12 (سطح میانای برنامه‌سازی کاربردی ۳۱) یا بالاتر، کاربران می‌توانند درخواست کنند که برنامه شما فقط اطلاعات مکان تقریبی را بازیابی کند، حتی زمانی‌که برنامه شما درخواست اجازه زمان اجرای ACCESS_FINE_LOCATION را دارد.

برای مدیریت این رفتار احتمالی کاربر، اجازه ACCESS_FINE_LOCATION را به‌تنهایی درخواست نکنید. درعوض، هر دو اجازه ACCESS_FINE_LOCATION و اجازه ACCESS_COARSE_LOCATION را در یک درخواست زمان اجرا درخواست کنید. اگر فقط برای ACCESS_FINE_LOCATION درخواست دهید، سیستم در برخی‌از نسخه‌های Android 12 درخواست را نادیده می‌گیرد. اگر برنامه شما Android 12 یا بالاتر را هدف قرار می‌دهد، سیستم پیام خطای زیر را در Logcat ثبت می‌کند:

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

وقتی برنامه‌تان هم ACCESS_FINE_LOCATION و هم ACCESS_COARSE_LOCATION را درخواست می‌کند، کادر گفتگوی اجازه‌های سیستم شامل گزینه‌های زیر برای کاربر است:

  • دقیق: به برنامه اجازه می‌دهد اطلاعات دقیق مکان را دریافت کند.
  • تقریبی: به برنامه اجازه می‌دهد فقط اطلاعات مکان تقریبی را دریافت کند.

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

در Android نسخه ۱۲ و بالاتر، کاربران می‌توانند به تنظیمات سیستم بروند تا دقت مکان ترجیحی را برای هر برنامه‌ای، صرف‌نظر از نسخه SDK هدف آن برنامه، تنظیم کنند. این موضوع حتی زمانی صادق است که برنامه شما در دستگاهی نصب شده باشد که Android نسخه ۱۱ یا پایین‌تر را اجرا می‌کند و سپس کاربر دستگاه را به Android نسخه ۱۲ یا بالاتر ارتقا دهد.

کادر گفتگو فقط به مکان تقریبی اشاره دارد و
         حاوی ۳ دکمه است که یکی بالای دیگری قرار دارد
شکل ۲. کادر گفتگوی اجازه‌های سیستم که وقتی برنامه‌تان فقط ACCESS_COARSE_LOCATION را درخواست می‌کند نشان داده می‌شود.
کادر گفتگو ۲ مجموعه گزینه دارد که یکی بالای دیگری است
شکل ۳. کادر گفتگوی اجازه‌های سیستم که وقتی برنامه شما هر دو ACCESS_FINE_LOCATION و ACCESS_COARSE_LOCATION را در یک درخواست زمان اجرا درخواست می‌کند، ظاهر می‌شود.

انتخاب کاربر بر اعطای اجازه تأثیر می‌گذارد

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

دقیق تقریبی
هنگام استفاده از برنامه ‫ACCESS_FINE_LOCATION و
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
فقط این بار ‫ACCESS_FINE_LOCATION و
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
رد کردن اجازه مکان وجود ندارد اجازه مکان وجود ندارد

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

کاتلین

@RequiresApi(Build.VERSION_CODES.N)
fun requestPermissions() {
    val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            }
            else -> {
                // No location access granted.
            }
        }
    }

    // Before you perform the actual permission request, check whether your app
    // already has the permissions, and whether your app needs to show a permission
    // rationale dialog. For more details, see Request permissions:
    // https://developer.android.com/training/permissions/requesting#request-permission
    locationPermissionRequest.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

جاوا

private void requestPermissions() {

    ActivityResultLauncher<String[]> locationPermissionRequest =
            registerForActivityResult(new ActivityResultContracts
                            .RequestMultiplePermissions(), result -> {

                Boolean fineLocationGranted = null;
                Boolean coarseLocationGranted = null;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    fineLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_FINE_LOCATION, false);
                    coarseLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_COARSE_LOCATION,false);
                }

                if (fineLocationGranted != null && fineLocationGranted) {
                    // Precise location access granted.
                } else if (coarseLocationGranted != null && coarseLocationGranted) {
                    // Only approximate location access granted.
                } else {
                    // No location access granted.
                }
            }
        );

    // ...

    // Before you perform the actual permission request, check whether your app
    // already has the permissions, and whether your app needs to show a permission
    // rationale dialog. For more details, see Request permissions.
    locationPermissionRequest.launch(new String[] {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    });
}

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

می‌توانید از کاربر بخواهید دسترسی برنامه‌تان را از مکان تقریبی به مکان دقیق ارتقا دهد. بااین‌حال، قبل‌از اینکه از کاربر بخواهید دسترسی برنامه‌تان را به مکان دقیق ارتقا دهد، بررسی کنید که آیا مورد استفاده برنامه‌تان واقعاً به این سطح از دقت نیاز دارد یا نه. اگر برنامه‌تان باید دستگاهی را با دستگاه‌های اطراف ازطریق بلوتوث یا Wi-Fi جفت کند، به‌جای درخواست اجازه ACCESS_FINE_LOCATION، از جفت‌سازی دستگاه همپا یا اجازه‌های بلوتوث استفاده کنید.

برای درخواست از کاربر برای ارتقای دسترسی به مکان برنامه‌تان از تقریبی به دقیق، کارهای زیر را انجام دهید:

  1. درصورت لزوم، توضیح دهید چرا برنامه‌تان به این اجازه نیاز دارد.
  2. اجازه‌های ACCESS_FINE_LOCATION و ACCESS_COARSE_LOCATION را دوباره باهم درخواست کنید. چون کاربر قبلاً به سیستم اجازه داده است مکان تقریبی را به برنامه‌تان اعطا کند، کادر گفتگوی سیستم این‌بار متفاوت است، همان‌طور که در شکل ۴ و شکل ۵ نشان داده شده است:
این کادر گفت‌وگو حاوی گزینه‌های «تغییر به مکان دقیق»، «فقط این‌بار»، و «رد کردن» است.
شکل ۴. کاربر قبلاً تقریبی و هنگام استفاده از برنامه را (در کادر گفتگوی شکل ۳) انتخاب کرده است.
کادر گفتگو حاوی گزینه‌های «فقط این‌بار» و
         «رد کردن» است.
شکل ۵. کاربر قبلاً تقریبی و فقط این‌بار را (در کادر گفتگوی شکل ۳) انتخاب کرده است.

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

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

شکل ۶ نمونه‌ای از برنامه‌ای را نشان می‌دهد که برای رسیدگی به درخواست‌های افزایشی طراحی شده است. هر دو ویژگی «نمایش مکان فعلی» و «توصیه مکان‌های اطراف» به دسترسی به مکان در پیش‌نما نیاز دارند. اما فقط ویژگی «توصیه مکان‌های اطراف» به دسترسی به مکان در پس‌زمینه نیاز دارد.

دکمه‌ای که دسترسی به مکان در پیش‌نما را فعال می‌کند
    به‌اندازه نصف طول صفحه از دکمه‌ای که مکان پس‌زمینه‌ای را فعال می‌کند
    فاصله دارد
شکل ۶. هر دو ویژگی به دسترسی به مکان نیاز دارند، اما فقط ویژگی «توصیه مکان‌های اطراف» به دسترسی به مکان در پس‌زمینه نیاز دارد.

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

  1. در ابتدا، برنامه‌تان باید کاربران را به ویژگی‌هایی هدایت کند که به دسترسی به مکان در پیش‌زمینه نیاز دارند، مثل ویژگی «هم‌رسانی مکان» در شکل ۱ یا ویژگی «نمایش مکان فعلی» در شکل ۲.

    توصیه می‌شود دسترسی کاربر به ویژگی‌هایی را که به دسترسی به مکان در پس‌زمینه نیاز دارند غیرفعال کنید تا زمانی که برنامه‌تان دسترسی به مکان در پیش‌نما را دریافت کند.

  2. بعداً، وقتی کاربر ویژگی‌هایی را کاوش می‌کند که به دسترسی به مکان در پس‌زمینه نیاز دارند، می‌توانید دسترسی به مکان در پس‌زمینه را درخواست کنید.

منابع بیشتر

برای کسب اطلاعات بیشتر درباره اجازه‌های مکان در Android، مطالب زیر را مشاهده کنید:

Codelabs

ویدیوها

نمونه‌ها