shouldShowRequestPermissionRationale एक Android API विधि है जो डेवलपर को बताती है कि खतरनाक अनुमति का अनुरोध करने से पहले उपयोगकर्ता को स्पष्टीकरण दिखाना चाहिए या नहीं। Android Developer Reference, 2024 के अनुसार, विधि true लौटाती है यदि उपयोगकर्ता ने पहले अनुरोध को अस्वीकार कर दिया था लेकिन Never Ask Again फ़्लैग सेट नहीं किया था। रनटाइम अनुमतियों के साथ काम करते समय विनम्र UX बनाने के लिए यह एक महत्वपूर्ण उपकरण है।
मुख्य बिंदु
shouldShowRequestPermissionRationale Android में Activity और Fragment वर्गों की एक विधि है, जो संगतता के लिए ActivityCompat के माध्यम से उपलब्ध है। यह एक अनुमति नाम लेती है और एक Boolean लौटाती है जो दर्शाती है कि पुनः अनुरोध करने से पहले उपयोगकर्ता को अतिरिक्त स्पष्टीकरण दिखाना चाहिए या नहीं। यह विधि Android 6.0 Marshmallow में रनटाइम अनुमति मॉडल के साथ दिखाई दी।
रैशनल तंत्र अनुमति डायलॉग के साथ उपयोगकर्ता की इंटरैक्शन इतिहास को ट्रैक करने पर बनाया गया है। सिस्टम याद रखता है कि उपयोगकर्ता ने पहले अनुरोध को अस्वीकार किया था या नहीं। यदि अस्वीकृति Never Ask Again फ़्लैग सेट किए बिना हुई, तो shouldShowRequestPermissionRationale true लौटाता है। यह डेवलपर के लिए एक संकेत है: उपयोगकर्ता नहीं समझता कि अनुमति की आवश्यकता क्यों है, और अतिरिक्त स्पष्टीकरण की आवश्यकता है। Google सामग्री डिज़ाइन दिशानिर्देशों के अनुसार, पहले इनकार के बाद रैशनल डायलॉग दिखाने से पुनः अनुमति प्रदान करने की संभावना 35 प्रतिशत बढ़ जाती है।
वापसी मानों के शब्दार्थ को समझना महत्वपूर्ण है: true का अर्थ है कि डायलॉग दिखाना समझ में आता है, false का अर्थ है कि डायलॉग या तो आवश्यक नहीं है (अनुमति पहले से प्रदान की गई है या कभी अनुरोधित नहीं की गई) या बेकार है (Never Ask Again सक्रिय)। विधि इस बात की गारंटी नहीं है कि डायलॉग दिखाया जाएगा — यह केवल एक सिफारिश देती है। डेवलपर तय करता है कि प्रतिक्रिया में कौन सा UI दिखाना है।
shouldShowRequestPermissionRationale को API स्तर 23 में रनटाइम अनुमतियों के लिए विधियों के एक समूह के साथ पेश किया गया था। Android 6.0 से पहले, सभी अनुमतियाँ स्थापना के समय अनुरोधित की जाती थीं, और किसी स्पष्टीकरण तंत्र की आवश्यकता नहीं थी — उपयोगकर्ता एक बार में पूरी सूची स्वीकार या अस्वीकार करता था। रनटाइम मॉडल ने यह संभव बनाया कि उपयोगकर्ता संदर्भ को समझे बिना अनुरोध को अस्वीकार कर सकता है, और यही कारण है कि रैशनल की आवश्यकता है।
विधि का तर्क इस प्रकार काम करता है। किसी विशिष्ट अनुमति के लिए requestPermissions के पहले कॉल पर, shouldShowRequestPermissionRationale false लौटाता है — उपयोगकर्ता ने अभी तक डायलॉग का सामना नहीं किया है। यदि उपयोगकर्ता अनुरोध को अस्वीकार करता है (Deny दबाता है), तो विधि true लौटाना शुरू कर देती है। Never Ask Again फ़्लैग के साथ बार-बार अस्वीकृति के बाद, विधि false लौटाती है।
पूर्ण स्थिति तालिका:
| स्थिति | shouldShowRationale | checkSelfPermission | डेवलपर कार्रवाई |
|---|---|---|---|
| अनुरोधित नहीं | false | DENIED | सिस्टम डायलॉग दिखाएँ |
| प्रदान की गई | false | GRANTED | फ़ंक्शन निष्पादित करें |
| पहली बार अस्वीकृत | true | DENIED | रैशनल दिखाएँ, फिर सिस्टम डायलॉग |
| Never Ask Again | false | DENIED | सेटिंग्स पर रीडायरेक्ट करें |
shouldShowRequestPermissionRationale = false और checkSelfPermission = DENIED का संयोजन संभालने के लिए सबसे कठिन मामला है। इसका अर्थ है कि या तो अनुमति कभी अनुरोधित नहीं की गई या Never Ask Again सेट है। डेवलपर को इन दो स्थितियों के बीच अंतर करने की आवश्यकता है। एकमात्र तरीका SharedPreferences में या SavedStateHandle का उपयोग करके isFirstRequest फ़्लैग संग्रहीत करना है। पहले अनुरोध पर फ़्लैग सेट करें, और यदि shouldShowRationale false लौटाता है जबकि फ़्लैग पहले से true है — तो इसका अर्थ Never Ask Again है।
shouldShowRequestPermissionRationale रीसेट हो जाता है यदि उपयोगकर्ता ऐप को अनइंस्टॉल और पुनः इंस्टॉल करता है, ऐप डेटा साफ़ करता है, या अनुमति सेटिंग्स रीसेट करता है। पुनः स्थापना के बाद, विधि पहले अनुरोध के लिए फिर से false लौटाएगी। सिस्टम अपडेट और Android संस्करण परिवर्तन इतिहास को रीसेट नहीं करते — यह ऐप डेटा में संग्रहीत होता है।
रैशनल का उचित कार्यान्वयन तीन घटक शामिल करता है: इनकार के बाद shouldShowRequestPermissionRationale की जाँच, स्पष्टीकरण के साथ एक कस्टम डायलॉग दिखाना, और उपयोगकर्ता की सकारात्मक प्रतिक्रिया के बाद requestPermissions को फिर से कॉल करना। डायलॉग संक्षिप्त, विशिष्ट होना चाहिए और बताना चाहिए कि ऐप को इस विशेष अनुमति की आवश्यकता क्यों है।
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()
}
सामग्री डिज़ाइन के सर्वोत्तम अभ्यास रैशनल के लिए मोडल डायलॉग के बजाय बॉटम शीट या इनलाइन बैनर का उपयोग करने की सलाह देते हैं। बॉटम शीट कम दखल देने वाली होती है और उपयोगकर्ता को संदर्भ देती है। स्क्रीन पर इनलाइन तत्व (उदाहरण के लिए, स्पष्टीकरण और अनुमति दें बटन वाला एक कार्ड) दिखाता है कि अनुमति के बिना फ़ंक्शन उपलब्ध नहीं है, लेकिन बाकी इंटरफ़ेस को अवरुद्ध नहीं करता।
रैशनल टेक्स्ट को स्थानीयकृत और विशिष्ट फ़ंक्शन के अनुकूल होना चाहिए। “ऐप के काम करने के लिए यह आवश्यक है” जैसे सामान्य वाक्यांशों का उपयोग न करें। विशेष रूप से निर्दिष्ट करें: “आपके पास मौसम दिखाने के लिए” या “फ़ोटो को गैलरी में सहेजने के लिए।” विशिष्ट स्पष्टीकरण Google UX अनुसंधान के अनुसार अनुमति प्रदान करने की संभावना को 50 प्रतिशत तक बढ़ाते हैं।
के बीच अंतर shouldShowRequestPermissionRationale = true (पहला इनकार) और DENIED के साथ false (Never Ask Again) अनुमति प्रबंधन में एक महत्वपूर्ण बिंदु है। पहले मामले में, उपयोगकर्ता झिझक रहा था, और अतिरिक्त स्पष्टीकरण उसे पहुँच प्रदान करने के लिए मना सकता है। दूसरे में, उपयोगकर्ता ने अंतिम निर्णय लिया, और सिस्टम डायलॉग को दोहराने से केवल जलन होगी।
इनकार के बाद प्रबंधन एल्गोरिथ्म इस प्रकार दिखना चाहिए:
क्रम को भ्रमित न करना महत्वपूर्ण है: पहले shouldShowRequestPermissionRationale की जाँच करें, checkSelfPermission की नहीं। checkSelfPermission दोनों मामलों में DENIED लौटाएगा। केवल shouldShowRequestPermissionRationale पहले इनकार को Never Ask Again से अलग करता है। “पहला अनुरोध किया गया था” फ़्लैग संग्रहीत करने के लिए SavedStateHandle या SharedPreferences का उपयोग करें — “कभी अनुरोधित नहीं” को “अवरुद्ध” से अलग करने का यही एकमात्र विश्वसनीय तरीका है।
रैशनल दिखाएँ केवल एक बार। यदि उपयोगकर्ता रैशनल देखने के बाद फिर से अनुरोध को अस्वीकार करता है, तो स्पष्टीकरण फिर से न दिखाएँ। सीधे सेटिंग्स खोलने की पेशकश पर जाएँ। बार-बार रैशनल दिखाना उत्पीड़न के रूप में माना जाता है और ऐप रेटिंग को कम करता है। इष्टतम परिदृश्य: अनुरोध — इनकार — रैशनल — पुनः अनुरोध — इनकार — सेटिंग्स।
पहले अनुरोध से पहले रैशनल न दिखाएँ। कुछ डेवलपर गलती से पहले डायलॉग से पहले स्पष्टीकरण दिखाते हैं, यह तर्क देते हुए कि “उपयोगकर्ता को समझना चाहिए।” यह UX को खराब करता है: उपयोगकर्ता एक के बजाय लगातार दो डायलॉग देखता है। Google अनुशंसा करता है तुरंत सिस्टम डायलॉग दिखाना, और रैशनल केवल इनकार के बाद।
प्रासंगिक रैशनल का उपयोग करें जो उस क्षण से जुड़ा हो जब फ़ंक्शन वास्तव में आवश्यक हो। ऐप स्टार्टअप पर सभी अनुमतियों का अनुरोध न करें — इसकी स्वीकृति दर सबसे कम है। कैमरा का अनुरोध तब करें जब उपयोगकर्ता “फ़ोटो लें” बटन दबाए और स्थान का अनुरोध तब करें जब वह मानचित्र खोले। प्रासंगिक अनुरोध रैशनल के साथ मिलकर स्वीकृति को स्टार्टअप पर अनुरोध करने पर 30 प्रतिशत की तुलना में 80 प्रतिशत तक बढ़ा देता है।
shouldShowRequestPermissionRationale का परीक्षण तालिका की चार स्थितियों की जाँच की आवश्यकता है: अनुरोधित नहीं, प्रदान की गई, अस्वीकृत, Never Ask Again। यूनिट परीक्षणों में, कॉन्फ़िगर करने योग्य shouldShowRationale व्यवहार के साथ FakePermissionHandler का उपयोग करें। इंस्ट्रुमेंटेशन परीक्षणों में, डायलॉग प्रतिक्रिया अनुकरण के साथ UiAutomator या Espresso का उपयोग करें।
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
)
}
}
इंस्ट्रुमेंटेशन परीक्षण के लिए मुख्य परिदृश्य यह सत्यापित करना है कि पहले इनकार के बाद रैशनल डायलॉग वास्तव में दिखाई देता है। सिस्टम डायलॉग की प्रतीक्षा करने के लिए idling resources के साथ Espresso का उपयोग करें, फिर Deny दबाएँ, कस्टम स्पष्टीकरण डायलॉग की उपस्थिति की जाँच करें, और Allow दबाएँ — प्रदान की गई की जाँच करें। UIAutomator बटन टेक्स्ट द्वारा सिस्टम डायलॉग के साथ बातचीत की अनुमति देता है, जो परीक्षण को अधिक स्थिर बनाता है।
रैशनल डायलॉग के अंदर इनकार परिदृश्य का भी परीक्षण करना चाहिए। यदि उपयोगकर्ता कस्टम स्पष्टीकरण में Deny दबाता है, तो shouldShowRequestPermissionRationale को फिर से true लौटाना चाहिए, क्योंकि Never Ask Again अभी तक सक्रिय नहीं हुआ है। सबसे अच्छा अभ्यास लगातार दो इनकार के बाद सेटिंग्स पर रीडायरेक्ट करना है ताकि उपयोगकर्ता को बार-बार स्पष्टीकरण से परेशान न किया जाए और ऐप रेटिंग कम न हो।
अक्सर पूछे जाने वाले प्रश्न
true — यदि अनुरोध पहले अस्वीकार किया गया था और Never Ask Again सेट नहीं है। false — यदि अनुमति कभी अनुरोधित नहीं की गई, प्रदान की गई या स्थायी रूप से अवरुद्ध है। false + DENIED के संयोजन के लिए अतिरिक्त फ़्लैग के माध्यम से जाँच की आवश्यकता है।
रैशनल केवल उपयोगकर्ता के पहले इनकार के बाद दिखाएँ, जब shouldShowRequestPermissionRationale ने true लौटाया हो। पहले अनुरोध से पहले रैशनल आवश्यक नहीं है — यह UX को खराब करता है और अनावश्यक डायलॉग बनाता है।
SharedPreferences या SavedStateHandle में isFirstRequest फ़्लैग संग्रहीत करें। यदि shouldShowRationale = false, checkSelfPermission = DENIED और फ़्लैग true है — तो Never Ask Again सक्रिय है। यदि फ़्लैग false है — यह पहला अनुरोध है।
“सेटिंग्स खोलें” बटन वाला एक डायलॉग दिखाएँ जो उपयोगकर्ता को ACTION_APPLICATION_DETAILS_SETTINGS पर रीडायरेक्ट करता है। requestPermissions को दोबारा कॉल न करें — डायलॉग दिखाई नहीं देगा, और परिणाम बिना संदेश के DENIED के रूप में वापस आएगा।
यूनिट परीक्षणों में, कॉन्फ़िगर करने योग्य shouldShowRationale फ़ील्ड के साथ FakePermissionHandler का उपयोग करें। इंस्ट्रुमेंटेशन परीक्षणों में, सिस्टम डायलॉग अनुकरण के साथ Espresso या UIAutomator का उपयोग करें। तालिका से सभी 4 स्थितियों की जाँच करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें