Here is the Simple Composable Function to Handle Audio Permission in Jetpack Compose Android Declarative UI Development.
@Composable
private fun HandleAudioPermission(
viewModel: AudioScreenViewModel,
onPermissionGranted:((isGranted:Boolean)->Unit)? = null
)
{
/** Now Check Or Request the Permissions **/
val context = LocalContext.current
val audioPermissionString = remember {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
{
Manifest.permission.READ_EXTERNAL_STORAGE
} else {
Manifest.permission.READ_MEDIA_AUDIO
}
} else {
Manifest.permission.WRITE_EXTERNAL_STORAGE
}
}
val permissions = remember { arrayOf(
audioPermissionString,
)}
val isAnyPermissionPermanentlyDenied by viewModel.isAnyPermissionPermanentlyDenied.collectAsState(false)
val allGranted = remember { mutableStateOf(
permissions.all {
ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
) }
val permissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions()
) { permissionsResult ->
permissions.forEach {
SharedPreferencesUtil.putBoolean(context,it,true)
}
allGranted.value = permissionsResult.all { it.value }
viewModel.updateMediaPermissionsGranted(allGranted.value)
viewModel.updateIsAnyPermissionPermanentlyDenied(viewModel.checkIsAnyPermissionPermanentlyDenied(context,permissions))
onPermissionGranted?.invoke(viewModel.mediaPermissionsGranted.value)
}
val settingsLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult()
) {
// Recheck permissions after returning from settings
allGranted.value = permissions.all {
ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
viewModel.updateMediaPermissionsGranted(allGranted.value)
onPermissionGranted?.invoke(viewModel.mediaPermissionsGranted.value)
}
viewModel.requestMediaPermissionCallback = {
if (!allGranted.value){
if (isAnyPermissionPermanentlyDenied) {
viewModel.openAppSettings(context,settingsLauncher)
} else {
permissionLauncher.launch(permissions)
}
}
}
if (allGranted.value)
{
viewModel.updateMediaPermissionsGranted(allGranted.value)
}
else{
viewModel.updateIsAnyPermissionPermanentlyDenied(viewModel.checkIsAnyPermissionPermanentlyDenied(context,permissions))
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = stringResource(R.string.PermissionMsgSounds),
color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyLarge,
)
Spacer(modifier = Modifier.height(5.dp))
Button(
modifier = Modifier
.testTag(TestTags.AllowPermission),
onClick = {
if (isAnyPermissionPermanentlyDenied) {
viewModel.openAppSettings(context,settingsLauncher)
} else {
permissionLauncher.launch(permissions)
}
}
) {
Text(if (isAnyPermissionPermanentlyDenied) "Open Settings" else "Allow Permissions")
}
}
}
}
How to Use this Composable Function?
Just Call this Composable function inside your Screen where you want to show permission dialog to the user.