Permission Handler ایک Android ایپلیکیشن جزو ہے جو رن ٹائم اجازتوں کی جانچ، درخواست اور نتائج کی پروسیسنگ کا ذمہ دار ہے۔ Android Developer Guide, 2024 کے مطابق، ایک اجازت ہینڈلر checkSelfPermission، requestPermissions اور shouldShowRequestPermissionRationale کی منطق کو ایک کلاس یا ViewModel میں مرکوز کرتا ہے۔ یہ کوڈ کی دیکھ بھال کو آسان بناتا ہے اور جانچ کو بہتر بناتا ہے۔
اہم نکات
Permission Handler Android رن ٹائم اجازتوں کے مرکزی انتظام کے لیے ایک آرکیٹیکچرل پیٹرن ہے۔ ایپلیکیشن کوڈ میں بکھری ہوئی ContextCompat.checkSelfPermission اور ActivityCompat.requestPermissions کالز کے بجائے، تمام درخواست اور نتائج کی پروسیسنگ منطق ایک کلاس میں مرتکز ہوتی ہے۔ یہ تکرار کو کم کرتا ہے، دیکھ بھال کو آسان بناتا ہے اور کوڈ کو زیادہ پیش قیاس بناتا ہے۔
Permission Handler کی ضرورت Android 6.0 میں رن ٹائم اجازتوں کے متعارف ہونے کے ساتھ پیدا ہوئی۔ اس سے پہلے، تمام اجازتیں انسٹالیشن کے وقت مانگی جاتی تھیں، اور ایپلیکیشن کوڈ بغیر جانچ کے کسی بھی API کو استعمال کر سکتا تھا۔ رن ٹائم ماڈل پر سوئچ کرنے کے بعد، خطرناک اجازت کے ہر استعمال کے لیے تین مرحلوں کی جانچ درکار ہوتی ہے: checkSelfPermission، requestPermissions، onRequestPermissionsResult۔ اس منطق کو Activity اور Fragment میں پھیلانے سے ان لائن تکرار اور غلطیاں پیدا ہوتی ہیں۔ Google I/O 2019 کے مطابق، اجازت کے انتظام کو مرکوز کرنے سے Permission Denial سے متعلق بگز کی تعداد اوسطاً 60 فیصد کم ہو جاتی ہے۔
ایک اچھا Permission Handler کالنگ کوڈ کے لیے ایک صاف انٹرفیس فراہم کرتا ہے۔ Activity یا Fragment کو درخواست کی تفصیلات جاننے کی ضرورت نہیں — وہ requestCamera(callback) جیسا طریقہ کال کرتے ہیں، اور ہینڈلر خود حیثیت کی جانچ، دلیل کی نمائش، سسٹم ڈائیلاگ کی دعوت اور نتیجہ callback تک پہنچانے کا انتظام کرتا ہے۔ یہ واحد ذمہ داری کے اصول کو لاگو کرتا ہے اور کاروباری منطق کو پلیٹ فارم اجازت کوڈ سے الگ کرتا ہے۔
Permission Handler اس وقت ضروری ہو جاتا ہے جب کوئی ایپلیکیشن 3 یا اس سے زیادہ خطرناک اجازتیں استعمال کرتی ہے۔ ایک اجازت (مثلاً QR کوڈ اسکینر کے لیے کیمرہ) والی سادہ ایپلیکیشنز کے لیے، براہ راست کال کافی ہو سکتی ہے۔ لیکن کیمرہ، جغرافیائی محل وقوع، اطلاعات اور اسٹوریج والی عام موبائل ایپلیکیشن کے لیے — ایک مرکزی ہینڈلر دیکھ بھال کے لیے ضروری ہے۔
ایک عام Permission Handler تین تہوں پر مشتمل ہوتا ہے: ایک انٹرفیس معاہدہ، ActivityResultLauncher کے ساتھ ایک نفاذ، اور ایک ViewModel تہہ۔ انٹرفیس ہر اجازت کے لیے درخواست کے طریقے متعین کرتا ہے — requestCamera، requestLocation، requestStorage۔ نفاذ ان طریقوں کو متعلقہ ActivityResultContracts.RequestPermission معاہدوں سے جوڑتا ہے۔
فن تعمیر کے اہم اجزاء:
یہ فن تعمیر ٹیسٹوں میں نفاذات کو آسانی سے تبدیل کرنے کی اجازت دیتا ہے: اصلی ActivityResultLauncher کے بجائے، ایک موک استعمال کیا جاتا ہے جو سسٹم کے تعامل کے بغیر پہلے سے طے شدہ نتیجہ لوٹاتا ہے۔ یہ UI منطق کے یونٹ ٹیسٹنگ کے لیے بہت اہم ہے، جہاں اجازت ڈائیلاگ کے لیے Activity شروع کرنا ناممکن ہے۔
Permission Handler کو Activity اور Fragment کے زندگی کے دورانیے کو مدنظر رکھنا چاہیے۔ لانچرز ActivityResultRegistry میں رجسٹر ہوتے ہیں، جو اسکرین گھومنے اور Activity کی دوبارہ تخلیق پر خود بخود حالت کو محفوظ اور بحال کرتا ہے۔ ہینڈلر کو Activity یا Fragment کے براہ راست حوالہ جات ذخیرہ نہیں کرنے چاہئیں — اس کے بجائے، WeakReference استعمال کریں یا کنسٹرکٹر کے ذریعے registry پاس کریں۔ یہ کنفیگریشن تبدیلیوں کے دوران میموری لیک اور کریش کو روکتا ہے۔
Permission Handler کا بنیادی نفاذ ActivityResultContracts.RequestPermission پر بنایا گیا ہے۔ ہینڈلر ComponentActivity یا Fragment سے ActivityResultRegistry وصول کرتا ہے اور ہر اجازت کے لیے لانچرز رجسٹر کرتا ہے۔ ہر لانچر ایک callback lambda قبول کرتا ہے جو صارف کے جواب دینے کے بعد دعوت دی جاتی ہے۔
sealed class PermissionResult {
object GRANTED : PermissionResult()
data class DENIED(
val shouldShowRationale: Boolean
) : PermissionResult()
}
interface PermissionHandler {
fun requestCamera(
callback: (PermissionResult) -> Unit
)
fun requestLocation(
callback: (PermissionResult) -> Unit
)
fun isPermissionGranted(
permission: String
): Boolean
}
class AndroidPermissionHandler(
private val registry: ActivityResultRegistry,
private val context: Context
) : PermissionHandler {
private var cameraLauncher: ActivityResultLauncher<String>? = null
fun initialize() {
cameraLauncher = registry.register(
"camera_permission",
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
pendingCameraCallback?.invoke(
PermissionResult.GRANTED
)
} else {
val rationale = ActivityCompat.shouldShowRequestPermissionRationale(
context as Activity,
Manifest.permission.CAMERA
)
pendingCameraCallback?.invoke(
PermissionResult.DENIED(rationale)
)
}
}
}
private var pendingCameraCallback:
((PermissionResult) -> Unit)? = null
override fun requestCamera(
callback: (PermissionResult) -> Unit
) {
if (isPermissionGranted(
Manifest.permission.CAMERA
)) {
callback.invoke(PermissionResult.GRANTED)
return
}
pendingCameraCallback = callback
cameraLauncher?.launch(
Manifest.permission.CAMERA
)
}
override fun isPermissionGranted(
permission: String
): Boolean {
return ContextCompat.checkSelfPermission(
context, permission
) == PackageManager.PERMISSION_GRANTED
}
}
ہینڈلر Activity کے onCreate میں registerForActivityResult کے ذریعے شروع کیا جاتا ہے، جو ActivityResultRegistry تک رسائی فراہم کرتا ہے۔ ابتداء کے بعد، ہینڈلر پورے Activity کے زندگی کے دورانیے میں درخواستوں پر کارروائی کرنے کے لیے تیار ہے۔ پہلی درخواست سے پہلے initialize کو کال کرنا ضروری ہے، ورنہ لانچر رجسٹر نہیں ہوگا۔
Permission Handler کو ViewModel کے ساتھ ضم کرنا سب سے جدید طریقہ ہے۔ ViewModel درخواستوں کی حالت کا انتظام کرتا ہے، جبکہ Handler صرف پلیٹ فارم کالز انجام دیتا ہے۔ ViewModel میں StateFlow<PermissionUiState> ہوتا ہے، جہاں UiState بیان کرتا ہے کہ کون سی اجازت مانگی جا رہی ہے اور کیا نتیجہ ملا ہے۔ Activity اس StateFlow کو سبسکرائب کرتی ہے اور درخواست Handler کو سونپتی ہے۔
class PermissionsViewModel : ViewModel() {
private val _uiState =
MutableStateFlow<PermissionUiState>(
PermissionUiState.Idle
)
val uiState: StateFlow<PermissionUiState> = _uiState.asStateFlow()
fun onCameraRequested() {
_uiState.value = PermissionUiState.RequestingCamera
}
fun onPermissionResult(
permission: String,
result: PermissionResult
) {
when (result) {
PermissionResult.GRANTED -> {
_uiState.value = PermissionUiState.Granted(permission)
}
is PermissionResult.DENIED -> {
_uiState.value = PermissionUiState.Denied(
permission,
result.shouldShowRationale
)
}
}
}
}
sealed class PermissionUiState {
object Idle : PermissionUiState()
object RequestingCamera : PermissionUiState()
data class Granted(val permission: String) : PermissionUiState()
data class Denied(
val permission: String,
val shouldShowRationale: Boolean
) : PermissionUiState()
}
اس ماڈل میں، Activity شروع ہونے پر Handler کے ذریعے isPermissionGranted چیک کرتی ہے، جبکہ ViewModel صرف حالت کا انتظام کرتا ہے۔ اگر اجازت نہیں دی گئی — Activity uiState کو سبسکرائب کرتی ہے، Handler سے requestCamera کال کرتی ہے اور نتیجہ onPermissionResult کے ذریعے ViewModel کو واپس بھیجتی ہے۔ پلیٹ فارم کوڈ کو کاروباری منطق سے الگ کرنا Android انحصار کے بغیر ViewModel کی جانچ کی اجازت دیتا ہے۔
PermissionHandler انٹرفیس کی بدولت Permission Handler کی یونٹ جانچ ممکن ہے۔ ٹیسٹوں میں، ایک FakePermissionHandler بنایا جاتا ہے جو مختلف منظرناموں کی نقل کرتا ہے: اجازت دی گئی، مسترد، Never Ask Again۔ ہر منظر نامہ آزادانہ طور پر جانچا جاتا ہے۔ یہ UI منطق کی جانچ کے لیے خاص طور پر اہم ہے جسے تینوں نتائج پر درست ردعمل دینا چاہیے۔
class FakePermissionHandler : PermissionHandler {
var cameraResult: PermissionResult =
PermissionResult.GRANTED
var grantedPermissions: Set<String> =
setOf(Manifest.permission.CAMERA)
override fun requestCamera(
callback: (PermissionResult) -> Unit
) {
callback.invoke(cameraResult)
}
override fun isPermissionGranted(
permission: String
): Boolean {
return permission in grantedPermissions
}
}
جعلی نفاذ ایمولیٹر کے بغیر ViewModel کی جانچ کی اجازت دیتا ہے۔ بس cameraResult کو مطلوبہ قدر پر سیٹ کریں اور تصدیق کریں کہ ViewModel اپنے UiState کو درست طریقے سے اپ ڈیٹ کرتا ہے۔ انضمام کے ٹیسٹ ActivityScenario کے ساتھ اصلی PermissionHandler کی جانچ کرتے ہیں، لیکن عام طور پر فی ایپلیکیشن صرف 2-3 ایسے ٹیسٹ ہوتے ہیں — باقی مناظر جعلی کے ساتھ یونٹ ٹیسٹوں سے احاطہ کیے جاتے ہیں۔
Permission Handler کے ساتھ کام کرتے وقت عام غلطیوں میں شامل ہیں: ہر API کال سے پہلے checkSelfPermission چیک نہ کرنا، shouldShowRequestPermissionRationale کو نظر انداز کرنا، Never Ask Again کے بعد requestPermissions کو دوبارہ کال کرنا اور Activity کے زندگی کے دورانیے پر غور کیے بغیر لانچرز کو ذخیرہ کرنا۔ آئیے ہر مسئلہ اور اس کے حل کا جائزہ لیتے ہیں۔
سب سے عام غلطی اجازت کی حیثیت چیک کیے بغیر API کو کال کرنا ہے۔ ڈویلپرز فرض کرتے ہیں کہ اگر ایک بار اجازت دی گئی تو یہ ہمیشہ رہے گی۔ تاہم، صارف کسی بھی وقت ترتیبات کے ذریعے اسے منسوخ کر سکتا ہے۔ ایک Permission Handler کو حساس آپریشن کرنے سے پہلے ہمیشہ isPermissionGranted کال کرنا چاہیے۔ دوسری عام غلطی shouldShowRequestPermissionRationale کو نظر انداز کرنا اور درخواست دہرانا ہے، جو Never Ask Again موڈ میں بغیر ڈائیلاگ کے فوری مستردی کا باعث بنتی ہے۔
بہترین طریقوں میں شامل ہیں: پورے Activity زندگی کے دورانیے کے لیے Handler کی ایک مثال بنانا، نتائج کو ViewModel تک پہنچانے کے لیے SharedFlow استعمال کرنا، تجزیہ کے لیے تمام درخواستوں اور مستردیوں کو لاگ کرنا، اور پہلی مستردی پر سسٹم ڈائیلاگ سے پہلے ایک کسٹم دلیل ڈائیلاگ دکھانا۔ ان اصولوں پر عمل کرنا Android کے تمام ورژنز پر مستحکم اجازت کے انتظام کی ضمانت دیتا ہے۔
اکثر پوچھے گئے سوالات
Permission Handler رن ٹائم اجازتوں کے مرکزی انتظام کے لیے ایک جزو ہے، جو checkSelfPermission، requestPermissions اور shouldShowRequestPermissionRationale کو سمیٹتا ہے۔ یہ کوڈ کی دیکھ بھال کو آسان بناتا ہے اور جانچ کو بہتر بناتا ہے۔
androidx.activity لائبریری سے ActivityResultContracts.RequestPermission استعمال کرنے کی سفارش کی جاتی ہے۔ یہ متروک onRequestPermissionsResult کو بدل دیتا ہے اور Boolean نتیجہ کے ساتھ ایک صاف callback API فراہم کرتا ہے۔
ایک اجازت کے لیے، Handler لازمی نہیں ہے — آپ Activity میں براہ راست RequestPermission لانچر کال استعمال کر سکتے ہیں۔ کوڈ کی تکرار سے بچنے کے لیے 3 یا زیادہ اجازتوں کے ساتھ Handler ضروری ہو جاتا ہے۔
یونٹ ٹیسٹوں کے لیے ایک PermissionHandler انٹرفیس اور اس کا جعلی نفاذ بنائیں۔ جعلی سسٹم کالز کے بغیر پہلے سے طے شدہ نتائج لوٹاتا ہے۔ یہ ایمولیٹر کے بغیر ViewModel اور UI منطق کی جانچ کی اجازت دیتا ہے۔
مستردی کے بعد، shouldShowRequestPermissionRationale چیک کریں۔ اگر طریقہ false لوٹاتا ہے — Never Ask Again موڈ فعال ہے۔ Handler کو PermissionResult.DENIED(false) لوٹانا چاہیے، اور UI کو ترتیبات میں جانے کے لیے ایک بٹن دکھانا چاہیے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں