Runtime Permissions

Runtime Permissions

Android 6.0+ requires runtime permissions for dangerous permissions. Proper implementation ensures security while maintaining good user experience.

// Runtime permission handling
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat

class PermissionManager(private val activity: AppCompatActivity) {
    
    private val requiredPermissions = arrayOf(
        Manifest.permission.CAMERA,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
    
    private val permissionLauncher = activity.registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        permissions.entries.forEach {
            val permission = it.key
            val isGranted = it.value
            
            if (isGranted) {
                onPermissionGranted(permission)
            } else {
                onPermissionDenied(permission)
            }
        }
    }
    
    fun checkAndRequestPermissions() {
        val permissionsToRequest = mutableListOf<String>()
        
        requiredPermissions.forEach { permission ->
            when {
                ContextCompat.checkSelfPermission(activity, permission) == 
                    PackageManager.PERMISSION_GRANTED -> {
                    // Permission already granted
                    onPermissionGranted(permission)
                }
                activity.shouldShowRequestPermissionRationale(permission) -> {
                    // Show explanation before requesting
                    showPermissionRationale(permission)
                    permissionsToRequest.add(permission)
                }
                else -> {
                    // Request permission directly
                    permissionsToRequest.add(permission)
                }
            }
        }
        
        if (permissionsToRequest.isNotEmpty()) {
            permissionLauncher.launch(permissionsToRequest.toTypedArray())
        }
    }
    
    private fun showPermissionRationale(permission: String) {
        val message = when (permission) {
            Manifest.permission.CAMERA -> "Camera access is needed to scan QR codes"
            Manifest.permission.ACCESS_FINE_LOCATION -> "Location access helps provide better service"
            else -> "This permission is required for app functionality"
        }
        
        // Show explanation dialog
    }
}