在 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】)


轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/357146.html
標籤:其他
下一篇:HOOK安卓so的至少5個函式
