طلب أذونات التشغيل

يعمل كل تطبيق Android في وضع حماية الوصول المحدود. إذا كان تطبيقك بحاجة إلى استخدام الموارد أو المعلومات خارج وضع الحماية الخاص به، يمكنك إعلان بيئة تشغيل إذن وإعداد طلب إذن الذي يوفّر إمكانية الوصول هذه هذه الخطوات هي جزء من سير العمل لاستخدام الأذونات.

إذا أعلنت عن وجود أي مخاطر الأذونات، وإذا كانت تثبيت تطبيقك على جهاز يعمل بالإصدار Android 6.0 (المستوى 23 من واجهة برمجة التطبيقات) أو أعلى، فيجب طلب الأذونات الخطيرة في وقت التشغيل من خلال اتباع الخطوات الواردة في هذا الدليل.

في حال عدم الإفصاح عن أي أذونات خطيرة أو إذا كان تطبيقك مثبتًا على جهاز يعمل بنظام التشغيل Android 5.1 (المستوى 22 لواجهة برمجة التطبيقات) أو أقل، تكون الأذونات تلقائيًا، ولا تحتاج إلى إكمال أي من الخطوات المتبقية في هذه الصفحة.

المبادئ الأساسية

في ما يلي المبادئ الأساسية لطلب الأذونات أثناء التشغيل:

  • طلب الإذن في السياق المناسب، عندما يبدأ المستخدم في التفاعل مع الميزة التي تتطلب ذلك.
  • لا تحظر المستخدم. توفير خيار إلغاء واجهة المستخدم التعليمية دائمًا التدفق، مثل التدفق الذي يشرح الأساس المنطقي لطلب الأذونات.
  • إذا رفض المستخدم إذنًا تحتاجه ميزة ما أو أبطله، على نحو رشيق تخفيض معدّل استخدام تطبيقك ليتمكن المستخدم من مواصلة استخدامه، وربما من خلال تعطيل الميزة التي تتطلب إذنًا.
  • لا تفترض أي سلوك للنظام. على سبيل المثال، لا تفترض أن الأذونات تظهر ضمن مجموعة الأذونات نفسها لا تساعد مجموعة الأذونات سوى إلى تخفيض عدد مربعات حوار النظام التي يتم تقديمها للمستخدم عند أن يطلب التطبيق أذونات وثيقة الصلة.

سير العمل لطلب الأذونات

قبل الإفصاح عن أذونات التشغيل في تطبيقك وطلبها، عليك تقييم ما إذا كان تطبيقك بحاجة إلى إجراء ذلك يمكنك تلبية العديد من حالات الاستخدام في تطبيقك، مثل التقاط الصور وإيقاف الوسائط مؤقتًا تشغيل وعرض إعلانات ملائمة بدون الحاجة إلى الإفصاح عن أي الأذونات.

إذا استنتجت أنّ تطبيقك يحتاج إلى تقديم بيان لطلب أذونات التشغيل وطلبها، أكمل هذه الخطوات:

  1. في ملف البيان لتطبيقك، عليك توضيح الأذونات التي قد يحتاج تطبيقك إليها طلبك.
  2. تصميم تجربة المستخدم لتطبيقك بحيث ترتبط الإجراءات المحددة في تطبيقك أذونات تشغيل محددة. السماح للمستخدمين بمعرفة الإجراءات التي قد تتطلب منهم لمنح تطبيقك إذنًا بالوصول إلى بيانات المستخدم الخاصة.
  3. انتظِر إلى أن يستدعي المستخدم المهمة أو الإجراء في تطبيقك يتطلب الوصول إلى بيانات مستخدم خاصة محددة. في ذلك الوقت، يمكن لتطبيقك تطلب إذن التشغيل المطلوب للوصول إلى هذه البيانات.
  4. التحقّق مما إذا سبق أن منح المستخدم بيئة التشغيل الإذن الذي يطلبه تطبيقك. إذا كان الأمر كذلك، سيتمكّن التطبيق من الوصول إلى بيانات المستخدم الخاصة. إذا لم يكن الأمر كذلك، انتقِل إلى الخطوة التالية.

    يجب عليك التحقق مما إذا كان لديك إذن في كل مرة تقوم فيها عملية تتطلب هذا الإذن.

  5. تحقَّق مما إذا كان يجب أن يعرض تطبيقك مبررًا منطقيًا للمستخدم. توضّح سبب احتياج التطبيق إلى أن يمنح المستخدِم إذنًا محدّدًا لوقت التشغيل. إذا حدّد النظام أنّ تطبيقك يجب ألا يقدّم مبررًا منطقيًا، يمكنك المتابعة الخطوة التالية مباشرة، دون إظهار عنصر في واجهة المستخدم.

    وإذا رأى النظام أنّ تطبيقك يجب أن يعرض مبررًا منطقيًا، تقديم الأساس المنطقي للمستخدم في عنصر واجهة المستخدم. في هذا الأساس، اشرَح بوضوح البيانات التي يحاول تطبيقك الوصول إليها والمزايا يمكن للتطبيق توفيره للمستخدم في حال منح إذن التشغيل. بعد يقر المستخدم بالأسباب، تابع إلى الخطوة التالية.

  6. اطلب إذن التشغيل الذي يتطلبه تطبيقك. الوصول إلى بيانات المستخدم الخاصة. يعرض النظام بيئة تشغيل طلب الحصول على أذونات، مثل الطلب الذي يظهر في نظرة عامة على الأذونات .

  7. تحقَّق من رد المستخدم - سواء اختار منح أو رفض إذن التشغيل.

  8. إذا منح المستخدم الإذن لتطبيقك، يمكنك الوصول إلى تطبيق خاص بيانات المستخدمين. إذا رفض المستخدم الإذن بدلاً من ذلك، يمكنك خفض مستوى تجربة التطبيق لكي يوفّر وظائف للمستخدم بدون المعلومات المحمية بموجب هذا الإذن.

يوضح الشكل 1 سير العمل ومجموعة القرارات المرتبطة بهذا المعالجة:

الشكل 1. مخطّط بياني يوضح سير العمل للإعلان تطلب أذونات التشغيل على نظام Android.

تحديد ما إذا سبق أن تم منح التطبيق الإذن

للتحقّق مما إذا كان المستخدم قد منح تطبيقك إذنًا معيّنًا من قبل، يُرجى اجتياز الاختبار هذا الإذن في ContextCompat.checkSelfPermission() . تُرجع هذه الطريقة إما PERMISSION_GRANTED أو PERMISSION_DENIED، وذلك حسب ما إذا كان تطبيقك قد حصل على الإذن أم لا.

يُرجى توضيح سبب احتياج التطبيق إلى الإذن.

مربّع حوار الأذونات الذي يعرضه النظام عند إجراء الاتصال يقول "requestPermissions()" نوع الإذن الذي يطلبه تطبيقك، لكنه لا يخبرك بذلك. والسبب وراء ذلك. في بعض الحالات، قد يجد المستخدم هذا اللغز. إنها لفكرة جيدة أن عليك توضيح سبب طلب التطبيق للأذونات قبل طلب البيانات requestPermissions()

وتوضح الأبحاث أن المستخدمين يكونون أكثر ارتياحًا لطلبات الأذونات إذا معرفة سبب احتياج التطبيق إليها، مثل ما إذا كان الإذن مطلوبًا تتيح ميزة أساسية في التطبيق أو لأغراض إعلانية نتيجة لذلك، إذا باستخدام جزء صغير فقط من طلبات البيانات من واجهة برمجة التطبيقات التي تندرج ضمن مجموعة أذونات، أن تسرد بشكلٍ صريح أيًا من هذه الأذونات التي تستخدمها وسبب استخدامها. بالنسبة على سبيل المثال، إذا كنت تستخدم الموقع التقريبي فقط، فأخبر المستخدم بذلك في وصف تطبيقك أو في مقالات المساعدة حول تطبيقك.

في ظل ظروف معينة، من المفيد أيضًا إخبار المستخدمين عن الوصول إلى البيانات الحساسة في الوقت الفعلي. على سبيل المثال، إذا كنت تصل إلى الكاميرا أو الميكروفون، من الأفضل إعلام المستخدم بذلك من خلال رمز الإشعار في مكانٍ ما داخل تطبيقك، أو في قائمة الإشعارات (إذا كانت يعمل في الخلفية)، لذلك لا يبدو أنك جمع البيانات خلسًا.

أخيرًا، إذا أردت طلب إذن لتنفيذ إجراء ما في تطبيقك ولكن السبب غير واضح للمستخدم، لذا ابحث عن طريقة للسماح للمستخدم تعرف لماذا تحتاج إلى الأذونات الأكثر حساسية.

إذا كانت طريقة 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(). لتقديم المزيد من المعلومات أو سياق المستخدم، غيِّر واجهة المستخدم في تطبيقك لتسهّل على المستخدمين فهم سبب احتياج إحدى الميزات في تطبيقك إلى إذن معيّن. بالنسبة سبيل المثال، يمكنك تغيير النص في الزر الذي يُمكّن الجديدة.

    كما يشير النص في مربع حوار أذونات النظام إلى إذن المجموعة المرتبطة بالإذن الذي طلبته. هذا النمط تم تصميم تجميع الأذونات لسهولة استخدام النظام، كما أن تطبيقك يجب ألا تعتمد على أذونات داخل نطاق معيّن أو خارجه مجموعة أذونات.

يعرض مقتطف الرمز التالي كيفية التعامل مع استجابة الأذونات:

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

إدارة رمز طلب الإذن بنفسك

كبديل للسماح للنظام بإدارة طلب الإذن الرمز، يمكنك إدارة طلب الحصول على إذن الترميز بنفسك. ولإجراء ذلك، عليك تضمين رمز الطلب في مكالمة 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 (مستوى واجهة برمجة التطبيقات 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 (مستوى واجهة برمجة التطبيقات 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 (المستوى 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. المرجع.

أذونات لمرة واحدة

الخيار المسمى &quot;هذه المرة فقط&quot; هو الثاني من بين ثلاثة أزرار في
    مربع الحوار.
الشكل 2. مربّع حوار النظام الذي يظهر عندما يطلب أحد التطبيقات على إذن لمرة واحدة.

بدءًا من الإصدار Android 11 (المستوى 30 لواجهة برمجة التطبيقات)، كلما طلب تطبيقك إذنًا المتعلقة بالموقع الجغرافي أو الميكروفون أو الكاميرا، فإن مربّع حوار الأذونات الموجّهة للمستخدمين يحتوي على خيار يُدعى هذه المرة فقط، كما هو موضح في الشكل 2. إذا حدد المستخدم هذا الخيار في يتم منح تطبيقك إذنًا لمرة واحدة مؤقتًا.

ويمكن لتطبيقك بعد ذلك الوصول إلى البيانات ذات الصلة لفترة زمنية تعتمد على سلوك تطبيقك وإجراءات المستخدم:

  • عندما يكون نشاط تطبيقك مرئيًا، يمكن لتطبيقك الوصول إلى البيانات.
  • إذا أرسل المستخدم تطبيقك إلى الخلفية، سيظل بإمكانه الوصول إلى التطبيق. البيانات لفترة زمنية قصيرة.
  • إذا تم تشغيل خدمة تعمل في المقدّمة وكان النشاط مرئيًا والمستخدم بعد ذلك نقل تطبيقك إلى الخلفية، يمكن للتطبيق مواصلة الوصول إلى البيانات. إلى أن تتوقف الخدمة التي تعمل في المقدّمة.

تنتهي عملية التطبيق عند إبطال الإذن.

إذا أبطل المستخدم الإذن الذي يُستخدم لمرة واحدة، كما هو الحال في إعدادات النظام، لا يمكن للتطبيق الوصول إلى البيانات، بغض النظر عمّا إذا كنت قد أطلقت واجهة برمجة تطبيقات خدمة ما. كما هو الحال مع أي إذن، إذا أبطل المستخدم تحديث التطبيق لمرة واحدة سيتم إنهاء عملية تطبيقك.

عندما يفتح المستخدم تطبيقك بعد ذلك وتطلب إحدى الميزات في تطبيقك الوصول إلى الموقع أو الميكروفون أو الكاميرا، سيُطلب من المستخدم الحصول على الإذن مرة أخرى.

إعادة ضبط الأذونات غير المستخدَمة

يوفّر Android عدة طرق لإعادة ضبط أذونات وقت التشغيل غير المستخدَمة على تلقائي، حالة الرفض:

إزالة إمكانية وصول التطبيقات إلى حسابكَ

على نظام التشغيل Android 13 (المستوى 33) والإصدارات الأحدث، يمكنك إزالة إمكانية وصول تطبيقك إلى أذونات التشغيل التي لم يعُد يتطلّبها تطبيقك. عند تحديث تطبيقك تنفيذ هذه الخطوة حتى يُرجح أن يستوعب المستخدمون سبب استخدام تطبيقك الاستمرار في طلب أذونات محددة. تساعد هذه المعرفة في بناء ثقة المستخدم. في تطبيقك.

لإزالة إمكانية الوصول إلى إذن تشغيل، عليك إدخال اسم ذلك الإذن. إلى revokeSelfPermissionOnKill() لإزالة إمكانية الوصول إلى مجموعة من أذونات التشغيل في الوقت نفسه، عليك إجراء مجموعة من أسماء الأذونات في revokeSelfPermissionsOnKill() تحدث عملية إزالة الإذن بشكل غير متزامن وتؤدي إلى إنهاء جميع العمليات والمرتبط بالمعرّف الفريد للتطبيق

لكي يزيل النظام إمكانية وصول تطبيقك إلى الأذونات، يجب إنهاء العمليات المرتبطة بتطبيقك. عند استدعاء واجهة برمجة التطبيقات، لا يعمل النظام تحدد متى يكون من الآمن إنهاء هذه العمليات. عادةً، ينتظر النظام إلى أن يقضي التطبيق فترة طويلة من الوقت قيد التشغيل في الخلفية بدلاً من المقدمة.

لإبلاغ المستخدم بأنّ تطبيقك لم يعُد يتطلّب الوصول إلى بيئة تشغيل محدَّدة الأذونات، يُظهر مربع حوار في المرة التالية التي يشغِّل فيها المستخدم تطبيقك. مربّع الحوار هذا قائمة الأذونات.

إعادة ضبط أذونات التطبيقات غير المستخدَمة تلقائيًا

إذا كان تطبيقك يستهدف الإصدار 11 من نظام التشغيل Android (المستوى 30 من واجهة برمجة التطبيقات) أو إصدارًا أحدث، ولم يتم استخدامه لبضعة يحمي النظام بيانات المستخدم من خلال إعادة تعيين أذونات التشغيل التي منحها المستخدم لتطبيقك مزيد من المعلومات في الدليل حول إسبات التطبيق.

طلب أن يصبح المعالج التلقائي إذا لزم الأمر

تعتمد بعض التطبيقات على الوصول إلى معلومات المستخدم الحسّاسة ذات الصلة بسجلات المكالمات. والرسائل القصيرة SMS. إذا كنت تريد طلب الأذونات الخاصة بسجلات المكالمات والرسائل القصيرة SMS ونشر التطبيق في متجر Play، يجب مطالبة ضبط تطبيقك باعتباره المعالج التلقائي لوظيفة نظام أساسية تطلب أذونات وقت التشغيل هذه.

لمزيد من المعلومات حول المعالجات التلقائية، بما في ذلك إرشادات حول عرض طلب المعالِج التلقائي للمستخدمين، يُرجى الاطّلاع على الدليل حول الأذونات المستخدمة فقط في المعالِجات التلقائية.

منح جميع أذونات التشغيل لأغراض الاختبار

لمنح جميع أذونات وقت التشغيل تلقائيًا عند تثبيت تطبيق على في جهاز اختباري أو محاكي، يمكنك استخدام الخيار -g بدلاً من adb shell install. كما هو موضح في مقتطف الرمز التالي:

adb shell install -g PATH_TO_APK_FILE

مصادر إضافية

للحصول على معلومات إضافية حول الأذونات، اطّلِع على المقالات التالية:

لمزيد من المعلومات حول طلب الأذونات، راجِع نماذج الأذونات

يمكنك أيضًا إكمال هذا الدرس التطبيقي حول الترميز الذي يوضّح الخصوصية بأفضل شكل الممارسات.