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

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

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

  • 代码环境如下:
    • 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】)

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>