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

    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'
    Ответ написан
    Комментировать
  • Как запустить проект на c++ в visual studio code?

    Прошло 2 года, и думаю, что автор вопроса уже нашел решение этой проблемы, но для тех, кто забрел сюда за решением, оставлю ссылку на статью, которая должна помочь.
    Ответ написан
    Комментировать