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

برای محافظت از حریم خصوصی کاربر، برنامه هایی که از خدمات مکان استفاده می کنند باید مجوزهای مکان را درخواست کنند.

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

این صفحه انواع مختلف الزامات موقعیت مکانی را شرح می دهد و راهنمایی هایی را در مورد نحوه درخواست مجوزهای مکان در هر مورد ارائه می دهد.

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

هر مجوز دارای ترکیبی از ویژگی های زیر است:

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

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

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

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

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

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

    <!-- 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 would go here. -->
    </service>

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

<manifest ... >
  <!-- Always include this permission -->
  <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 از سطوح زیر از دقت مکان پشتیبانی می کند:

تقریبی
تخمین موقعیت مکانی دستگاه را ارائه می دهد. اگر این تخمین مکان از LocationManagerService یا FusedLocationProvider باشد، این تخمین در حدود 3 کیلومتر مربع (حدود 1.2 مایل مربع) دقیق است. وقتی مجوز ACCESS_COARSE_LOCATION را اعلام می‌کنید، اما مجوز ACCESS_FINE_LOCATION نه، برنامه شما می‌تواند مکان‌هایی با این سطح از دقت دریافت کند.
دقیق
تخمین موقعیت مکانی دستگاه را ارائه می دهد که تا حد امکان دقیق باشد. اگر تخمین مکان از LocationManagerService یا FusedLocationProvider باشد، این تخمین معمولاً در حدود 50 متر (160 فوت) است و گاهی اوقات به اندازه چند متر (10 فوت) یا بهتر است. با اعلام مجوز ACCESS_FINE_LOCATION ، برنامه شما می‌تواند مکان‌هایی با این سطح از دقت دریافت کند.

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

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

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

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

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

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

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

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

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

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

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

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

کاتلین

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.
locationPermissionRequest.launch(arrayOf(
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION))

جاوا

ActivityResultLauncher<String[]> locationPermissionRequest =
    registerForActivityResult(new ActivityResultContracts
        .RequestMultiplePermissions(), result -> {
            Boolean fineLocationGranted = result.getOrDefault(
                    Manifest.permission.ACCESS_FINE_LOCATION, false);
            Boolean 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 را با هم درخواست کنید. از آنجایی که کاربر قبلاً به سیستم اجازه داده است تا مکان تقریبی را به برنامه شما اعطا کند، گفتگوی سیستم این بار متفاوت است، همانطور که در شکل 4 و شکل 5 نشان داده شده است:
گفتگو حاوی گزینه های 'تغییر به دقیق است          مکان»، «فقط این بار» و «انکار».
شکل 4. کاربر قبلاً Approximate و When using app را انتخاب کرده بود (در گفتگوی شکل 3 ).
گفتگو حاوی گزینه های "فقط این بار" و          'انکار'.
شکل 5. کاربر قبلاً Approximate و Only this time را انتخاب کرده بود (در گفتگوی شکل 3 ).

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

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

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

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

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

  1. در ابتدا، برنامه شما باید کاربران را به ویژگی هایی راهنمایی کند که به دسترسی به موقعیت پیش زمینه نیاز دارند، مانند ویژگی «اشتراک گذاری مکان» در شکل 1 یا ویژگی «نمایش مکان فعلی» در شکل 2.

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

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

در صورت لزوم موقعیت پس زمینه را درخواست کنید

شکل 7. صفحه تنظیمات شامل گزینه ای به نام Allow all time است که به موقعیت مکانی پس زمینه دسترسی می دهد.

محتویات گفتگوی مجوز به نسخه SDK هدف بستگی دارد

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

با این حال، در اندروید 11 (سطح API 30) و بالاتر، کادر گفتگوی سیستم شامل گزینه Allow all time نیست. در عوض، کاربران باید موقعیت پس‌زمینه را در صفحه تنظیمات فعال کنند، همانطور که در شکل 7 نشان داده شده است.

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

برنامه اندروید 11 یا بالاتر را هدف قرار می دهد

اگر به برنامه شما مجوز ACCESS_BACKGROUND_LOCATION اعطا نشده است و shouldShowRequestPermissionRationale() true را برگرداند، یک رابط کاربری آموزشی به کاربران نشان دهید که شامل موارد زیر است:

  • توضیح واضح در مورد اینکه چرا ویژگی برنامه شما نیاز به دسترسی به موقعیت مکانی پس زمینه دارد.
  • برچسب قابل مشاهده توسط کاربر گزینه تنظیمات که موقعیت پس‌زمینه را اعطا می‌کند (به عنوان مثال، Allow all time در شکل 7). برای دریافت این برچسب می توانید getBackgroundPermissionOptionLabel() فراخوانی کنید. مقدار بازگشتی این روش به ترجیح زبان دستگاه کاربر محلی سازی شده است.
  • گزینه ای برای کاربران برای رد کردن مجوز. اگر کاربران دسترسی به موقعیت مکانی پس‌زمینه را رد کنند، باید بتوانند به استفاده از برنامه شما ادامه دهند.
کاربران می توانند برای تغییر مکان روی اعلان سیستم ضربه بزنند   تنظیمات یک برنامه
شکل 8. اعلانی که به کاربر یادآوری می کند که به یک برنامه دسترسی به موقعیت مکانی پس زمینه داده است.

برنامه اندروید 10 یا پایین‌تر را هدف قرار می‌دهد

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

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

کاربر می تواند بر دقت موقعیت مکانی پس زمینه تأثیر بگذارد

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

یادآوری اعطای موقعیت مکانی پس زمینه

در Android 10 و بالاتر، وقتی یک ویژگی در برنامه شما برای اولین بار پس از اعطای دسترسی کاربر به موقعیت مکانی پس‌زمینه، به موقعیت مکانی دستگاه در پس‌زمینه دسترسی پیدا می‌کند، سیستم اعلانی را برای ارسال به کاربر برنامه‌ریزی می‌کند. این اعلان به کاربر یادآوری می‌کند که به برنامه شما اجازه داده است همیشه به مکان دستگاه دسترسی داشته باشد. یک نمونه اعلان در شکل 8 نشان داده شده است.

الزامات مکان را در وابستگی های SDK برنامه خود بررسی کنید

بررسی کنید که آیا برنامه شما از SDKهایی استفاده می‌کند که به مجوزهای مکان، به ویژه مجوز ACCESS_FINE_LOCATION بستگی دارد یا خیر. در مورد آشنایی با رفتارهای وابستگی های SDK خود با این مقاله در Medium مشورت کنید.

منابع اضافی

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

Codelabs

ویدیوها

نمونه ها