📱 Device Features · Lesson 35
Runtime Permissions
Normal vs dangerous permissions
| Type | Examples | आप क्या करते हैं |
|---|---|---|
| Normal | INTERNET, VIBRATE, ACCESS_NETWORK_STATE | Manifest में declare — अपने आप मिलती है |
| Dangerous (runtime) | CAMERA, location, RECORD_AUDIO, READ_CONTACTS, POST_NOTIFICATIONS (13+) | Declare और app चलते समय user से माँगें |
| अब ज़रूरत नहीं | Photos चुनना (Photo Picker), sharing (intents), dialing (ACTION_DIAL) | System UI use करें |
Permission flow
Step 1: Manifest में declare
XML
<!-- AndroidManifest.xml --> <uses-permission android:name="android.permission.INTERNET" /> <!-- normal --> <uses-permission android:name="android.permission.CAMERA" /> <!-- dangerous --> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- dangerous, API 33+ --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Step 2: Check और request
Kotlin
class ScanActivity : AppCompatActivity() {
// 1. register BEFORE the activity is started (as a property)
private val cameraPermission = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (granted) openCamera()
else Snackbar.make(binding.root, "Camera permission is needed to scan", Snackbar.LENGTH_LONG).show()
}
private fun onScanClicked() {
when {
// 2. already granted?
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED -> openCamera()
// 3. user denied once → explain why first
shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> showRationale()
// 4. ask
else -> cameraPermission.launch(Manifest.permission.CAMERA)
}
}
}Step 3: समझाएँ और denial संभालें
Kotlin
private fun showRationale() {
MaterialAlertDialogBuilder(this)
.setTitle("Allow camera?")
.setMessage("We use the camera only to scan your ID card. Photos stay on your phone.")
.setNegativeButton("Not now", null)
.setPositiveButton("Continue") { _, _ -> cameraPermission.launch(Manifest.permission.CAMERA) }
.show()
}
// Permanently denied → open the app's settings page
private fun openAppSettings() {
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)))
}एक साथ कई permissions
Kotlin
private val locationPermissions = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { result ->
val fine = result[Manifest.permission.ACCESS_FINE_LOCATION] == true
val coarse = result[Manifest.permission.ACCESS_COARSE_LOCATION] == true
when {
fine -> startPreciseLocation()
coarse -> startApproximateLocation()
else -> showNoLocationMessage()
}
}
locationPermissions.launch(arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
))असली example: notifications (Android 13+)
Kotlin – Student Diary
// Student Diary – MainActivity
private val notificationPermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (!granted) {
Snackbar.make(binding.root, R.string.notifications_off, Snackbar.LENGTH_LONG).show()
}
}
private fun askNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !NotificationHelper.canNotify(this)) {
notificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
// NotificationHelper
fun canNotify(context: Context): Boolean =
Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU ||
ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTEDआम गलतियाँ
- App start पर हर permission माँगना → users deny करते हैं; feature use होने पर माँगें।
- Click के अंदर
registerForActivityResult→ crash; property की तरह register करें। - Manifest entry भूलना → dialog कभी नहीं दिखता और result हमेशा false।
- Android 12 या नीचे POST_NOTIFICATIONS माँगना → ज़रूरत नहीं; SDK version check करें।
सारांश
- Normal permissions: सिर्फ़ manifest। Dangerous: manifest + runtime request।
checkSelfPermission→ rationale →RequestPermissionlauncher → callback।- हो सके तो permission-free system UIs (Photo Picker, intents) use करें।
✅ Practice
"Scan QR" button जोड़िए जो rationale dialog के साथ camera permission माँगे, और permanently deny होने पर "Open Settings" Snackbar action दिखाए।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
Photo चुनने के लिए storage permission चाहिए?
नहीं। Android Photo Picker (PickVisualMedia) बिना किसी permission के चुनी हुई image का access देता है।
User दो बार deny करे तो क्या होता है?
Android 11+ पर system dialog दिखाना बंद कर देता है ("don't ask again")। Request तुरंत false लौटाती है; user को app के Settings page पर भेजें।
क्या INTERNET runtime permission है?
नहीं। INTERNET normal permission है: manifest में declare करना काफ़ी है।
