shouldShowRequestPermissionRationale في Android — ما هو، منطق العرض والتطبيق

المؤلف: IT Sectr نُشر: 2026-05-20 وقت القراءة: 8 دق

shouldShowRequestPermissionRationale هو أسلوب من واجهة برمجة تطبيقات Android يخبر المطور ما إذا كان يجب عرض شرح للمستخدم قبل طلب إذن خطير. وفقًا لـ مرجع مطوري Android، 2024، فإن الأسلوب يعيد true إذا كان المستخدم قد رفض الطلب سابقًا ولكن لم يضع علامة Never Ask Again. هذه أداة رئيسية لبناء تجربة مستخدم مهذبة عند العمل مع أذونات وقت التشغيل.

النقاط الرئيسية

  • shouldShowRequestPermissionRationale — أسلوب يحدد ما إذا كان يجب عرض شرح قبل طلب الإذن.
  • يعيد true بعد رفض المستخدم الأول إذا كان Never Ask Again غير مفعل.
  • يعيد false إذا لم يتم طلب الإذن مطلقًا، أو تم منحه، أو محظور بشكل دائم.
  • يستخدم لعرض حوار مخصص يشرح سبب الحاجة إلى إذن محدد.
  • عند never ask again (false + denied)، يجب توجيه المستخدم إلى الإعدادات.

ما هو shouldShowRequestPermissionRationale

shouldShowRequestPermissionRationale هو أسلوب في الفئتين Activity وFragment في Android، متاح من خلال ActivityCompat للتوافق. يستقبل اسم إذن ويعيد Boolean يشير إلى ما إذا كان يجب عرض شرح إضافي للمستخدم قبل الطلب مرة أخرى. ظهر الأسلوب في Android 6.0 Marshmallow مع نموذج أذونات وقت التشغيل.

آلية التبرير مبنية على تتبع تاريخ تفاعل المستخدم مع حوارات الأذونات. يتذكر النظام ما إذا كان المستخدم قد رفض الطلب سابقًا. إذا حدث الرفض دون تعيين علامة Never Ask Again، يعيد shouldShowRequestPermissionRationale القيمة true. هذه إشارة للمطور: المستخدم لا يفهم سبب الحاجة إلى الإذن، وهناك حاجة إلى شرح إضافي. وفقًا لـ إرشادات تصميم المواد من Google، فإن عرض حوار التبرير بعد الرفض الأول يزيد من احتمالية منح الإذن مرة أخرى بنسبة 35 بالمائة.

من المهم فهم دلالات القيم المعادة: true تعني أن عرض الحوار منطقي، false تعني أن الحوار إما غير مطلوب (الإذن ممنوح بالفعل أو لم يُطلب مطلقًا) أو غير مفيد (Never Ask Again نشط). الأسلوب ليس ضمانًا بأن الحوار سيتم عرضه — إنه يعطي توصية فقط. المطور هو من يقرر واجهة المستخدم التي سيتم عرضها ردًا على ذلك.

متى تم تقديم الأسلوب

تم تقديم shouldShowRequestPermissionRationale في مستوى API 23 مع مجموعة من الأساليب لأذونات وقت التشغيل. قبل Android 6.0، كانت جميع الأذونات تُطلب عند التثبيت، ولم تكن هناك حاجة لآلية شرح — كان المستخدم يقبل أو يرفض القائمة بأكملها مرة واحدة. نموذج وقت التشغيل جعل من الممكن أن يرفض المستخدم طلبًا دون فهم السياق، وهذا هو بالضبط سبب الحاجة إلى التبرير.

كيف يعمل shouldShowRequestPermissionRationale

منطق الأسلوب يعمل على النحو التالي. في أول استدعاء لـ requestPermissions لإذن معين، يعيد shouldShowRequestPermissionRationale القيمة false — لم يواجه المستخدم الحوار بعد. إذا رفض المستخدم الطلب (ضغط رفض)، يبدأ الأسلوب في إعادة true. بعد رفض متكرر مع علامة Never Ask Again، يعيد الأسلوب false.

جدول الحالات الكامل:

الحالةshouldShowRationalecheckSelfPermissionإجراء المطور
لم يُطلبfalseDENIEDعرض حوار النظام
ممنوحfalseGRANTEDتنفيذ الوظيفة
مرفوض أول مرةtrueDENIEDعرض التبرير، ثم حوار النظام
Never Ask AgainfalseDENIEDتوجيه إلى الإعدادات

الجمع بين shouldShowRequestPermissionRationale = false و checkSelfPermission = DENIED هو أصعب حالة للمعالجة. يعني ذلك إما أن الإذن لم يُطلب مطلقًا أو أن Never Ask Again مفعل. يحتاج المطور إلى التمييز بين هاتين الحالتين. الطريقة الوحيدة هي تخزين علامة isFirstRequest في SharedPreferences أو باستخدام SavedStateHandle. قم بتعيين العلامة في الطلب الأول، وإذا أعاد shouldShowRationale القيمة false بينما العلامة بالفعل true — فهذا يعني Never Ask Again.

إعادة تعيين الحالة

يتم إعادة تعيين shouldShowRequestPermissionRationale إذا قام المستخدم بإلغاء تثبيت التطبيق وإعادة تثبيته، أو مسح بيانات التطبيق، أو إعادة تعيين إعدادات الأذونات. بعد إعادة التثبيت، سيعيد الأسلوب القيمة false للطلب الأول مرة أخرى. تحديثات النظام وتغييرات إصدار Android لا تعيد تعيين السجل — فهو مخزن في بيانات التطبيق.

تنفيذ حوار التبرير

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

kotlin
private fun requestLocationWithRationale() {
    val permission = Manifest.permission.ACCESS_FINE_LOCATION

    when {
        ContextCompat.checkSelfPermission(
            this, permission
        ) == PackageManager.PERMISSION_GRANTED -> {
            startLocationTracking()
        }
        ActivityCompat.shouldShowRequestPermissionRationale(
            this, permission
        ) -> {
            showRationaleDialog(permission)
        }
        else -> {
            requestPermissionLauncher.launch(permission)
        }
    }
}

private fun showRationaleDialog(
    permission: String
) {
    AlertDialog.Builder(this)
        .setTitle("لماذا تحتاج إلى الوصول إلى الموقع")
        .setMessage(
            "يستخدم التطبيق الموقع لوضع علامات" +
            " على الأماكن على الخريطة. بدون هذا الإذن،" +
            " لن تعمل الوظيفة."
        )
        .setPositiveButton("سماح") { _, _ ->
            requestPermissionLauncher.launch(permission)
        }
        .setNegativeButton("إلغاء", null)
        .show()
}

أنماط واجهة المستخدم للتبرير

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

توطين التبرير

يجب توطين نص التبرير وتكييفه مع الوظيفة المحددة. لا تستخدم عبارات عامة مثل «هذا مطلوب لكي يعمل التطبيق.» حدد بشكل ملموس: «لعرض الطقس بالقرب منك» أو «لحفظ الصور في المعرض.» التفسيرات المحددة تزيد من احتمالية منح الإذن بنسبة 50 بالمائة وفقًا لأبحاث تجربة المستخدم من Google.

التبرير مقابل Never Ask Again

الفرق بين shouldShowRequestPermissionRationale = true (الرفض الأول) و false مع DENIED (Never Ask Again) هو نقطة رئيسية في معالجة الأذونات. في الحالة الأولى، كان المستخدم مترددًا، والشرح الإضافي قد يقنعه بمنح الوصول. في الحالة الثانية، اتخذ المستخدم قرارًا نهائيًا، وتكرار حوار النظام لن يسبب سوى الانزعاج.

يجب أن تكون خوارزمية المعالجة بعد الرفض على النحو التالي:

  • الحصول على نتيجة DENIED من رد اتصال الطلب
  • استدعاء shouldShowRequestPermissionRationale
  • إذا كانت true — عرض حوار تبرير مخصص مع زر إعادة المحاولة
  • إذا كانت false — عرض حوار مع زر فتح الإعدادات

من المهم عدم الخلط بين الترتيب: تحقق من shouldShowRequestPermissionRationale أولاً، وليس checkSelfPermission. سيستمر checkSelfPermission في إرجاع DENIED في كلتا الحالتين. فقط shouldShowRequestPermissionRationale يميز الرفض الأول عن Never Ask Again. استخدم SavedStateHandle أو SharedPreferences لتخزين علامة «تم الطلب الأول» — هذه هي الطريقة الوحيدة الموثوقة للتمييز بين «لم يُطلب مطلقًا» و «محظور.»

أفضل الممارسات لعرض التبرير

اعرض التبرير مرة واحدة فقط. إذا رفض المستخدم الطلب مرة أخرى بعد رؤية التبرير، لا تعرض الشرح مرة أخرى. انتقل مباشرة إلى عرض فتح الإعدادات. عرض التبرير بشكل متكرر يُنظر إليه على أنه إزعاج ويقلل من تقييم التطبيق. السيناريو الأمثل: طلب — رفض — تبرير — طلب متكرر — رفض — الإعدادات.

لا تعرض التبرير قبل الطلب الأول. بعض المطورين يعرضون خطأً شرحًا قبل أول حوار، بحجة أن «المستخدم يجب أن يفهم.» هذا يضر بتجربة المستخدم: يرى المستخدم حوارين متتاليين بدلاً من واحد. توصي Google بعرض حوار النظام فورًا، والتبرير فقط بعد الرفض.

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

اختبار سيناريوهات التبرير

اختبار shouldShowRequestPermissionRationale يتطلب التحقق من حالات الجدول الأربع: لم يُطلب، ممنوح، مرفوض، Never Ask Again. في اختبارات الوحدة، استخدم FakePermissionHandler مع سلوك shouldShowRationale قابل للتكوين. في اختبارات الأجهزة، استخدم UiAutomator أو Espresso مع محاكاة استجابات الحوار.

kotlin
class RationaleViewModelTest {

    private val handler = FakePermissionHandler()
    private val viewModel = PermissionsViewModel(handler)

    fun testFirstDenial_shouldShowRationale() {
        handler.shouldShowRationale = true
        handler.cameraResult =
            PermissionResult.DENIED(true)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.Denied(true),
            viewModel.uiState.value
        )
    }

    fun testNeverAskAgain_redirectToSettings() {
        handler.shouldShowRationale = false
        handler.cameraResult =
            PermissionResult.DENIED(false)

        viewModel.onCameraRequested()

        assertEquals(
            PermissionUiState.RedirectToSettings,
            viewModel.uiState.value
        )
    }
}

السيناريو الرئيسي لاختبار الأجهزة هو التحقق من أن حوار التبرير يظهر بالفعل بعد الرفض الأول. استخدم Espresso مع موارد الانتظار لانتظار حوار النظام، ثم اضغط رفض، وتحقق من ظهور حوار التبرير المخصص، واضغط سماح — وتحقق من المنح. UIAutomator يسمح بالتفاعل مع حوار النظام من خلال نص الزر، مما يجعل الاختبار أكثر استقرارًا.

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

الأسئلة الشائعة

ماذا يعيد shouldShowRequestPermissionRationale؟

true — إذا كان الطلب قد رُفض سابقًا ولم يتم تعيين Never Ask Again. false — إذا لم يُطلب الإذن مطلقًا، أو تم منحه، أو تم حظره بشكل دائم. الجمع بين false + DENIED يتطلب التحقق من خلال علامة إضافية.

متى يتم عرض حوار التبرير؟

اعرض التبرير فقط بعد الرفض الأول للمستخدم، عندما يكون shouldShowRequestPermissionRationale قد أعاد true. قبل الطلب الأول، التبرير غير مطلوب — هذا يضعف تجربة المستخدم ويخلق حوارات غير ضرورية.

كيف نميز الطلب الأول عن Never Ask Again؟

قم بتخزين علامة isFirstRequest في SharedPreferences أو SavedStateHandle. إذا كان shouldShowRationale = false، checkSelfPermission = DENIED والعلامة true — فهذا يعني أن Never Ask Again نشط. إذا كانت العلامة false — فهذا هو الطلب الأول.

ماذا تفعل عند Never Ask Again؟

اعرض حوارًا مع زر «فتح الإعدادات» الذي يوجه المستخدم إلى ACTION_APPLICATION_DETAILS_SETTINGS. لا تستدع requestPermissions مرة أخرى — لن يظهر الحوار، وستعود النتيجة كـ DENIED بدون رسالة.

كيف تختبر shouldShowRequestPermissionRationale؟

في اختبارات الوحدة، استخدم FakePermissionHandler مع حقل shouldShowRationale قابل للتكوين. في اختبارات الأجهزة، استخدم Espresso أو UIAutomator مع محاكاة حوار النظام. تحقق من جميع الحالات الأربع من الجدول.

الخلاصة

  • shouldShowRequestPermissionRationale — أسلوب يحدد ما إذا كان يجب عرض شرح قبل طلب الإذن.
  • يعيد true بعد الرفض الأول دون Never Ask Again، وfalse في ثلاث حالات أخرى.
  • الجمع بين false + DENIED هو السيناريو الأصعب، ويتطلب علامة إضافية للتمييز.
  • يتم عرض حوار التبرير فقط بعد الرفض، وليس قبل الطلب الأول.
  • استخدم لوحة سفلية أو عنصرًا مضمنًا بدلاً من حوار مشروط لتجربة مستخدم أفضل.
  • عند تفعيل Never Ask Again — قم بالتوجيه إلى الإعدادات عبر ACTION_APPLICATION_DETAILS_SETTINGS.
  • التبرير السياقي المرتبط بلحظة استخدام الوظيفة يزيد من المنح إلى 80 بالمائة.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا