Jetpack Compose 动态权限申请(Permission Request)

news/2024/11/9 12:14:21

在 Jetpack Compose 动态申请权限可以使用两种方法

  • rememberLancherForActivityResult
  • Accompanist 的 Permissions

接下来分贝展示一下两种用法

  • 代码环境如下:
    • Kotlin 1.5.2
    • Jetpack Compose 1.0.2
    • Android Studio Chipmunk | 2021.2.1

要使用 Accompanist 需要额外引入

dependencies {
	...
    implementation "com.google.accompanist:accompanist-permissions:0.16.1"
	...
}

1. rememberLauncherForActivityResult 方式

rememberLauncherForActivityResult 是基于 Activity 的 ResultAPI 获取动态权限。例如我们可以在新打开一个 Activity 时通过这种方式获取权限:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            RequestPermission()
        }
    }
}

@Composable
private fun RequestPermission() {
    // 基于 LocalComposition 获取 Context
    val context = LocalContext.current

    // 基于 LocalLifecycleOwner 获取 Lifecycle
    val lifecycle = LocalLifecycleOwner.current.lifecycle

    // 定义需要动态获取的 Permission 类型
    val permission = Manifest.permission.READ_EXTERNAL_STORAGE

    // Result API 调用时的 launcher
    val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestPermission(),
        onResult = { isGranted -> 
        	//判断权限申请结果,并根据结果侠士不同画面,由于 onResult 不是一个 @Composable lambda,所以不能直接显示 Composalbe 需要通过修改 state 等方式间接显示 Composable
        }
    )

    // 在 Activity onStart 时,发起权限事情,如果权限已经获得则跳过
    val lifecycleObserver = remember {
        LifecycleEventObserver { _, event ->
            if (event == Lifecycle.Event.ON_START) {
                if (!permission.isGrantedPermission(context)) {
                    launcher.launch(permission)
                }
            }
        }
    }

    // 当 Lifecycle 或者 LifecycleObserver 变化时注册回调,注意 onDispose 中的注销处理避免泄露
      DisposableEffect(lifecycle, lifecycleObserver) {
        lifecycle.addObserver(lifecycleObserver)
        onDispose {
            lifecycle.removeObserver(lifecycleObserver)
        }
    }
}

private fun String.isGrantedPermission(context: Context): Boolean {
    // 判断是否已经后的状态
    return context.checkSelfPermission(this) == PackageManager.PERMISSION_GRANTED
}

当进入 MainActivity 时请求权限的效果
在这里插入图片描述

2. Accompanist Permissions方式

Accompanist Permission 将权限申请结果以一个 Composable State 的形式返回,调用形式相较于第一种更加易用 。比如,我们通过该点击按钮动态申请权限

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            RequestPermissionUsingAccompanist()
        }
    }
}

@OptIn(ExperimentalPermissionsApi::class)
@Composable
private fun RequestPermissionUsingAccompanist() {
    val permission = Manifest.permission.READ_EXTERNAL_STORAGE

    // 定义 Permission State
    val permissionState = rememberPermissionState(permission)
    PermissionRequired(
        permissionState = permissionState,
        permissionNotAvailableContent = {
            // 权限获取失败
            Text("Permission Denied.")
        }, permissionNotGrantedContent = {
            // 尚未获取权限时
            Button(onClick = { permissionState.launchPermissionRequest() }) {
                Text("Request permission.")
            }
        }, content = {
            // 权限获取成功
            Text("Permission Granted.")
        }
    )
}

代码非常清晰,PermissionRequired 接收几个 Composable lambda 的参数,分别对应权限申请后,不同处理下的回调:

  • permissionNotGrantedContent:尚未获取权限或者获取失败(点击【Deny】)
  • permissionNotAvailableContent:点击【Deny & don’t ask again】时
  • content : 获取成功(点击【Allow】)

在这里插入图片描述
在这里插入图片描述


http://www.niftyadmin.cn/n/2071158.html

相关文章

Kotlin 1.6 正式发布,都有哪些新特性?

11月16日,Kotlin 1.6 正式对外发布。接下来就一起看一下在这个版本中都有哪些新的语法特性 更安全的when语句(exhaustive when statements)挂起函数类型可作父类 (suspending functions as supertypes )普通函数转挂起…

【Android】实战图像识别:Compose + MLKit + CameraX

MLKit 是 Google 提供的移动端机器学习库,可以在 Andorid 或 iOS 上低成本地实现各种 AI 能力,例如图像、文字、人脸识别等等,而且很多能力可以在手机端离线完成。 https://developers.google.com/ml-kit 下面通过代码示例展示 MLKit 的以下功…

Jetpack Compose 易犯错误之:在 LazyColumn 中访问 LazyListState

我们在使用 LazyColumn 或者 LazyRow 时&#xff0c;应该避免在 LazyListScope 中访问 LazyListState&#xff0c;这可能会造成隐藏的性能问题&#xff0c;看下面的代码&#xff1a; Composable fun VerticalList(items: List<String>, onReachedBottom: () -> Unit)…

Compose Multiplatform 正式版将于年内发布

近日&#xff0c;JetBrains 公司发布了 Compose Multiplatform 的 Beta 版本&#xff0c;这距离此前 Alpha 版本的发布才过去两个多月。 这个版本中包含了许多新的改进&#xff0c;在桌面端与Web端分别增加了新的 API &#xff0c;并对已有的部分 APIs 进行了稳定。Beta 版的发…

对标 VSCode?JetBrains 下一代编辑器 Fleet

11 月 29 日 JetBrains 官方发布了全新的轻量级编辑器 Fleet&#xff0c;并号称是基于20年IDE开发经验打造的“新一代 IDE”。 Fleet 的定位更加纯粹&#xff0c;聚焦编辑器功能而非替代现有的 IDE 产品。据推测 Fleet 的推出主要是 JetBrains 为了对抗微软的 VSCode &#xff…

10个问题带你看懂 Compose Multiplatform 1.0

近日 JetBrains 正式发布了 Compose Multiplatform 1.0 版&#xff0c;这标志其在生产环境中使用的时机已经成熟。相信有不少人对它还不太熟悉&#xff0c;本文通过下面 10 个热门问题带大家认识这一最新的跨平台技术。 FAQ&#xff1a; 与 Jetpack Compose 的关系? 是否会取代…

Jetpack MVVM 七宗罪之四: 使用 LiveData/StateFlow 发送 Events

久违的 “ Jetpack MVVM 七宗罪 ” 系列&#xff0c;今日再开。本系列主要盘点 MVVM 架构中各种常见错误写法&#xff0c;并针对性的给出最佳实践&#xff0c;帮助大家掌握 Jetpack 组件最正确的使用姿势。 Jetpack MVVM 七宗罪之一: 拿 Fragment 当 LifecycleOwnerJetpack MVV…

Jetpack MVVM 七宗罪之五: 在 Repository 中使用 LiveData

前言 现在的 Android 项目中几乎少不了对 LiveData 的使用。MVP 时代我们需要定义各种 IXXXView 实现与 Presenter 的通信&#xff0c;而现在已经很少见到类似的接口定义了&#xff0c;大家早已习惯了用响应式的思想设计表现层与逻辑层之间的通信&#xff0c;这少不了 LiveData…