xref: /aosp_15_r20/external/accompanist/docs/permissions.md (revision fa44fe6ae8e729aa3cfe5c03eedbbf98fb44e2c6)
1*fa44fe6aSInna Palant# Jetpack Compose Permissions
2*fa44fe6aSInna Palant
3*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-permissions)](https://search.maven.org/search?q=g:com.google.accompanist)
4*fa44fe6aSInna Palant
5*fa44fe6aSInna PalantA library which provides [Android runtime permissions](https://developer.android.com/guide/topics/permissions/overview) support for Jetpack Compose.
6*fa44fe6aSInna Palant
7*fa44fe6aSInna Palant!!! warning
8*fa44fe6aSInna Palant    The permission APIs are currently experimental and they could change at any time.
9*fa44fe6aSInna Palant    All of the APIs are marked with the `@ExperimentalPermissionsApi` annotation.
10*fa44fe6aSInna Palant
11*fa44fe6aSInna Palant## Usage
12*fa44fe6aSInna Palant
13*fa44fe6aSInna Palant### `rememberPermissionState` and `rememberMultiplePermissionsState` APIs
14*fa44fe6aSInna Palant
15*fa44fe6aSInna PalantThe `rememberPermissionState(permission: String)` API allows you to request a certain permission
16*fa44fe6aSInna Palantto the user and check for the status of the permission.
17*fa44fe6aSInna Palant`rememberMultiplePermissionsState(permissions: List<String>)` offers the same but for multiple
18*fa44fe6aSInna Palantpermissions at the same time.
19*fa44fe6aSInna Palant
20*fa44fe6aSInna PalantBoth APIs expose properties for you to follow the workflow as described in the
21*fa44fe6aSInna Palant[permissions documentation](https://developer.android.com/training/permissions/requesting#workflow_for_requesting_permissions).
22*fa44fe6aSInna Palant
23*fa44fe6aSInna Palant!!! caution
24*fa44fe6aSInna Palant    The call to the method that requests the permission to the user (e.g. `PermissionState.launchPermissionRequest()`)
25*fa44fe6aSInna Palant    needs to be invoked from a non-composable scope. For example, from a side-effect or from a
26*fa44fe6aSInna Palant    non-composable callback such as a `Button`'s `onClick` lambda.
27*fa44fe6aSInna Palant
28*fa44fe6aSInna PalantThe following code exercises the [permission request workflow](https://developer.android.com/training/permissions/requesting#workflow_for_requesting_permissions).
29*fa44fe6aSInna Palant
30*fa44fe6aSInna Palant```kotlin
31*fa44fe6aSInna Palant@OptIn(ExperimentalPermissionsApi::class)
32*fa44fe6aSInna Palant@Composable
33*fa44fe6aSInna Palantprivate fun FeatureThatRequiresCameraPermission() {
34*fa44fe6aSInna Palant
35*fa44fe6aSInna Palant    // Camera permission state
36*fa44fe6aSInna Palant    val cameraPermissionState = rememberPermissionState(
37*fa44fe6aSInna Palant        android.Manifest.permission.CAMERA
38*fa44fe6aSInna Palant    )
39*fa44fe6aSInna Palant
40*fa44fe6aSInna Palant    if (cameraPermissionState.status.isGranted) {
41*fa44fe6aSInna Palant        Text("Camera permission Granted")
42*fa44fe6aSInna Palant    } else {
43*fa44fe6aSInna Palant        Column {
44*fa44fe6aSInna Palant            val textToShow = if (cameraPermissionState.status.shouldShowRationale) {
45*fa44fe6aSInna Palant                // If the user has denied the permission but the rationale can be shown,
46*fa44fe6aSInna Palant                // then gently explain why the app requires this permission
47*fa44fe6aSInna Palant                "The camera is important for this app. Please grant the permission."
48*fa44fe6aSInna Palant            } else {
49*fa44fe6aSInna Palant                // If it's the first time the user lands on this feature, or the user
50*fa44fe6aSInna Palant                // doesn't want to be asked again for this permission, explain that the
51*fa44fe6aSInna Palant                // permission is required
52*fa44fe6aSInna Palant                "Camera permission required for this feature to be available. " +
53*fa44fe6aSInna Palant                    "Please grant the permission"
54*fa44fe6aSInna Palant            }
55*fa44fe6aSInna Palant            Text(textToShow)
56*fa44fe6aSInna Palant            Button(onClick = { cameraPermissionState.launchPermissionRequest() }) {
57*fa44fe6aSInna Palant                Text("Request permission")
58*fa44fe6aSInna Palant            }
59*fa44fe6aSInna Palant        }
60*fa44fe6aSInna Palant    }
61*fa44fe6aSInna Palant}
62*fa44fe6aSInna Palant```
63*fa44fe6aSInna Palant
64*fa44fe6aSInna PalantFor more examples, refer to the [samples](https://github.com/google/accompanist/tree/main/sample/src/main/java/com/google/accompanist/sample/permissions).
65*fa44fe6aSInna Palant
66*fa44fe6aSInna Palant## Limitations
67*fa44fe6aSInna Palant
68*fa44fe6aSInna PalantThis permissions wrapper is built on top of the available Android platform APIs. We cannot extend
69*fa44fe6aSInna Palantthe platform's capabilities. For example, it's not possible to differentiate between the
70*fa44fe6aSInna Palant_it's the first time requesting the permission_ vs _the user doesn't want to be asked again_
71*fa44fe6aSInna Palantuse cases.
72*fa44fe6aSInna Palant
73*fa44fe6aSInna Palant## Download
74*fa44fe6aSInna Palant
75*fa44fe6aSInna Palant[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-permissions)](https://search.maven.org/search?q=g:com.google.accompanist)
76*fa44fe6aSInna Palant
77*fa44fe6aSInna Palant```groovy
78*fa44fe6aSInna Palantrepositories {
79*fa44fe6aSInna Palant    mavenCentral()
80*fa44fe6aSInna Palant}
81*fa44fe6aSInna Palant
82*fa44fe6aSInna Palantdependencies {
83*fa44fe6aSInna Palant    implementation "com.google.accompanist:accompanist-permissions:<version>"
84*fa44fe6aSInna Palant}
85*fa44fe6aSInna Palant```
86*fa44fe6aSInna Palant
87*fa44fe6aSInna PalantSnapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. These are updated on every commit.
88*fa44fe6aSInna Palant
89*fa44fe6aSInna Palant[compose]: https://developer.android.com/jetpack/compose
90*fa44fe6aSInna Palant[snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/accompanist/accompanist-permissions/
91