Как запрашивать разрешения в Android Jetpack Compose?

Хотел бы узнать, как запрашивать разрешения в compose-приложении. Буду рад, если будут примеры.
  • Вопрос задан
  • 521 просмотр
Решения вопроса 1
yalexaner
@yalexaner Автор вопроса
Написал ответ на свой вопрос на StackOverflow, используя ответ, который немного отредактировал и разобрал, от 2jan222.

Нужно создать composable и использовать его, когда необходима функция, для которой нужно получить разрешение. В него — передать массив разрешений permissions, код запроса requestCode (любое число) и две или больше лямбды: onGranted — будет использоваться, когда разшенеие будет дано —, onDenied — в обратном случае.

@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()
    }
}


Ещё нужно имплементировать ambient. Как я понял, он передаётся детям composables. Здесь — AmbientPermissionHandler будет передан в PermissionsRequest из Providers.

val AmbientPermissionHandler = ambientOf<PermissionHandler>()


PermissionHandler. Он будет передан в PermissionRequest в виде AmbientPermissionHandler, используя Providers.

class PermissionHandler(private val context: AppCompatActivity) {
    suspend fun requestPermissions(
        requestCode: Int,
        permissions: Array<out String>
    ): PermissionResult {
        return PermissionManager.requestPermissions(context, requestCode, *permissions)
    }
}


Затем испоьзуется примерно так:

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 */ }
                )
            }
        }
    }
}


Создать PermissionHandler в активити MainActivity, а потом передаётся внутри setContent, используя Providers.

Для PermissionManager и LaunchedEffect нужны зависимости:

implementation 'com.sagar:coroutinespermission:2.0.3'
implementation 'androidx.compose.runtime:runtime:1.0.0-alpha11'
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы