In android jetpack compose when using accompanist permission how to detect if user revoked permission i.e. denied permission twice
R

2

5

I want to know how to detect when the user has revoked permission(denied permission twice) in the accompanist permission library, I also checked the library's GitHub repository and samples are old.

I am using,

compose_version = '1.2.0-alpha03'

accompanist_version = '0.24.2-alpha'

Here is my code snippet,

@ExperimentalMaterial3Api
@ExperimentalPermissionsApi
@Composable
fun CameraPermission() {
    /* Camera permission state.*/
    val cameraPermissionState = rememberPermissionState(permission = Manifest.permission.CAMERA)

    val context = LocalContext.current
    val intent =Intent(
        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
        Uri.fromParts("package", BuildConfig.APPLICATION_ID, null))

    when (cameraPermissionState.status) {

        /* If the camera permission is granted, then show screen with the feature enabled.*/
        PermissionStatus.Granted -> {
            Text("Camera permission Granted")
        }

        is PermissionStatus.Denied -> {
            /*
            * This is a rationale explaining why we need the camera permission.
            * We are displaying this because the user has denied the permission once.
            * */
            if (cameraPermissionState.status.shouldShowRationale) {
                /*
                * If the user has denied the permission but the rationale can be shown, then gently
                * explain why the app requires this permission
                * */
                Column {
                    Text(text = "The camera is important for this app. Please grant the permission.")
                    Button(onClick = { cameraPermissionState.launchPermissionRequest() }) {
                        Text("Grant permission")
                    }
                }
            } else {
                /*
                * If it's the first time the user lands on this feature, or the user doesn't want to
                * be asked again for this permission, explain that the permission is required
                * */
                Column {
                    Text(text = "Camera permission required for this feature to be available. Please grant the permission")
                    Button(onClick = { cameraPermissionState.launchPermissionRequest() }) {
                        Text("Grant permission")
                    }

/*todo("permission denied twice.")*/
                    Text(text = "Camera permission denied twice. Please grant the permission")
                    Button(
                        onClick = {
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            context.startActivity(intent)
                        }
                    ) {
                        Text("Open settings to grant permission.")
                    }
                }
            }
        }
    }
}
Rod answered 20/2, 2022 at 5:26 Comment(2)
See github.com/google/accompanist/issues/… for the initial trick to make this possible. You'll need the current 0.24.3-alpha, the API may change. It's about location permissions, but the concept is the same for your problem.Gainey
All answers based on shouldShowRationale won't work well because the rationale is different depending on versions of Android. Check my implementation based on time difference: https://mcmap.net/q/325777/-how-request-permissions-with-jetpack-composeHaydeehayden
M
9

you need to start launchPermissionRequest to have enough information

var permissionAlreadyRequested by rememberSaveable {
    mutableStateOf(false)
}

val cameraPermissionState = rememberPermissionState(permission = Manifest.permission.CAMERA) {
    permissionAlreadyRequested = true
}

if (!permissionAlreadyRequested && !cameraPermissionState.shouldShowRationale) {
    SideEffect {
        cameraPermissionState.launchPermissionRequest()
    }
} else if (cameraPermissionState.shouldShowRationale) {
    ShowRationaleContent {
        cameraPermissionState.launchPermissionRequest()
    }
} else {
    ShowOpenSettingsContent {
        context.openSettings()
    }
}
Mistranslate answered 8/3, 2022 at 10:51 Comment(3)
Can they make this any harder for developers :faceslap:Lindbergh
wow! I didn't know there is an onPermissionResult callback in rememberPermissionState.Miliary
Nice! The rememberPermissionState callback should be clear in the accompanist documentation.Socorrosocotra
H
3

If any one wants for multi permission . This is how I had to handle it

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun RequestPermission(context: Context?,onPermissionsGranted:()->Unit) {
    val permissionAlreadyRequested = rememberSaveable {
        mutableStateOf(false)
    }

    val permissionState = rememberMultiplePermissionsState(
        permissions =
            listOf(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
            )
    ) {
        permissionAlreadyRequested.value = true
        if (!it.values.contains(false)){
            onPermissionsGranted.invoke()
        }
    }

    if (!permissionAlreadyRequested.value && !permissionState.shouldShowRationale) {
        SideEffect {
            permissionState.launchMultiplePermissionRequest()
        }
    } else if (permissionState.shouldShowRationale) {
        ShowRationaleContent {
            permissionState.launchMultiplePermissionRequest()
        }

    } else {
        ShowOpenSettingsContent {
            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            val uri: Uri = Uri.fromParts("package", context.packageName, null)
            intent.data = uri
            context.startActivity(intent)
        }
    }

}
Havstad answered 12/12, 2022 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.