A
A
Alexander Yachmenev2021-02-01 21:13:37
Android
Alexander Yachmenev, 2021-02-01 21:13:37

How to request permissions in Android Jetpack Compose?

I would like to know how to request permissions in a compose application. I will be glad if there are examples.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexander Yachmenev, 2021-02-02
@yalexaner

Wrote an answer to my own question on StackOverflow , using the answer , edited and parsed slightly, by 2jan222 .
You need to create a composable and use it when you need a feature that needs permission. In it - pass an array of permissions permissions, a request code requestCode(any number) and two or more lambdas: onGranted- will be used when permission is given -, onDenied- otherwise.

@Composable
fun PermissionsRequest(
    permissions: Array<out String>,
    requestCode: Int,
    onGranted: @Composable () -> Unit,
    onDenied: @Composable () -> Unit,
    onDeniedPermanently: (@Composable () -> Unit)? = null,
    rational: (@Composable () -> Unit)? = null,
    awaitResult: (@Composable () -> Unit)? = null,
) {
    val permissionHandler = AmbientPermissionHandler.current
    val (permissionResult, setPermissionResult) = remember(permissions) {
        mutableStateOf<PermissionResult?>(null)
    }

    LaunchedEffect(Unit) {
        setPermissionResult(permissionHandler.requestPermissions(requestCode, permissions))
    }

    when (permissionResult) {
        is PermissionResult.PermissionGranted -> onGranted()
        is PermissionResult.PermissionDenied -> onDenied()
        is PermissionResult.PermissionDeniedPermanently -> onDeniedPermanently?.invoke()
        is PermissionResult.ShowRational -> rational?.invoke()
        null -> awaitResult?.invoke()
    }
}

Still need to implement ambient. As I understand it, it is passed to composables children. Here - AmbientPermissionHandlerwill be passed to PermissionsRequestfrom Providers.
val AmbientPermissionHandler = ambientOf<PermissionHandler>()

PermissionHandler. It will be passed in PermissionRequestas AmbientPermissionHandler, using Providers.
class PermissionHandler(private val context: AppCompatActivity) {
    suspend fun requestPermissions(
        requestCode: Int,
        permissions: Array<out String>
    ): PermissionResult {
        return PermissionManager.requestPermissions(context, requestCode, *permissions)
    }
}

Then used like this:
class MainActivity : AppCompatActivity() {
    private val permissionHandler = PermissionHandler(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Providers(
                AmbientPermissionHandler provides permissionHandler
            ) {
                PermissionsRequest(
                    permissions = arrayOf(Manifest.permission.READ_SMS),
                    requestCode = PERMISSION_REQUEST_CODE,
                    onGranted = { /* Here goes the composables when the permission is granted */ },
                    onDenied = { /* Is used when the permission is denied */ }
                )
            }
        }
    }
}

Create PermissionHandlerin activity MainActivityand then passed inside setContentusing Providers.
For PermissionManagerand LaunchedEffectyou need dependencies:
implementation 'com.sagar:coroutinespermission:2.0.3'
implementation 'androidx.compose.runtime:runtime:1.0.0-alpha11'

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question