Jetpack Compose 的最佳处理运行时权限的方法

news/2024/11/24 11:37:30/

Jetpack Compose 的最佳处理运行时权限的方法

android permission in Jetpack compose
如果您的应用安装在运行Android 6.0(API级别23)或更高版本的设备上,则必须按照本指南中的步骤为用户请求运行时权限。

在Jetpack Compose中获取运行时权限有两种方法。

  • 使用Activity Result
  • 使用Accompanist Permissions库

接下来,让我们仔细研究上述两种方法,并附有示例。

使用Activity Result进行运行时权限

第一步是在manifest.xml文件中定义权限。


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"/>

在这个示例应用程序中,我使用相机权限示例来捕获图像。请查看我的其他示例,以了解如何使用相机捕获图像。

如何在 jetpack compose 中使用相机捕获图像 (howtodoandroid.com)

https://www.howtodoandroid.com/capture-image-in-jetpack-compose/

如何在 jetpack compose 中从图库选择图像 (howtodoandroid.com)

https://www.howtodoandroid.com/pick-image-from-gallery-jetpack-compose/

创建一个活动结果启动器来请求我们定义的权限。一旦启动,它将返回结果,无论该权限是否被授予。

val permissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {if (it) {Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()cameraLauncher.launch(uri)} else {Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()}}

检查权限

在请求权限之前,我们需要检查权限是否已经被授予。如果已经授予,我们可以继续正常流程。如果权限未被授予,那么我们需要使用我们需要的权限来发起权限请求。

val permissionCheckResult = ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA)if (permissionCheckResult == PackageManager.PERMISSION_GRANTED) {cameraLauncher.launch(uri)} else {permissionLauncher.launch(android.Manifest.permission.CAMERA)}

最后,使用活动结果实现运行时权限的代码将如下所示:


val context = LocalContext.currentval file = context.createImageFile()val uri = FileProvider.getUriForFile(Objects.requireNonNull(context),BuildConfig.APPLICATION_ID + ".provider", file)var capturedImageUri by remember {mutableStateOf<Uri>(Uri.EMPTY)}val cameraLauncher =rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) {capturedImageUri = uri}val permissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {if (it) {Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()cameraLauncher.launch(uri)} else {Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()}}Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(12.dp)) {Button(onClick = {val permissionCheckResult = ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA)if (permissionCheckResult == PackageManager.PERMISSION_GRANTED) {cameraLauncher.launch(uri)} else {// Request a permissionpermissionLauncher.launch(android.Manifest.permission.CAMERA)}}) {Text(text = "Open Camera")}if (capturedImageUri.path?.isNotEmpty() == true) {Image(modifier = Modifier.padding(16.dp, 8.dp).fillMaxWidth().size(400.dp),painter = rememberImagePainter(capturedImageUri),contentDescription = null)}}

上面的效果如下:
在这里插入图片描述

请求多个权限

在某些情况下,我们需要一次请求多个权限,例如,位置权限。为此,我们需要使用不同的启动器方法和权限检查。我们来详细看看。

像往常一样,我们需要在 manifest.xml 文件中定义所需的权限。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

需要的第一步是创建包含我们要请求的权限列表。

val permissions = arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION)

使用ActivityResultContracts.RequestMultiplePermissions() 方法一次性请求多个权限。使用此函数并创建权限启动器。

val launcherMultiplePermissions = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissionsMap ->val areGranted = permissionsMap.values.reduce { acc, next -> acc && next }if (areGranted) {Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()} else {Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()}}

现在,启动器已准备好进行多个权限。下一步是检查权限是否已经授予。如果没有授予,则使用权限列表启动权限启动器。

if(permissions.all {ContextCompat.checkSelfPermission(context,it) == PackageManager.PERMISSION_GRANTED
}) {// Get the location
} else {launcherMultiplePermissions.launch(permissions)
}

请求多个运行时权限的最终代码将是:

val permissions = arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION)val launcherMultiplePermissions = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissionsMap ->val areGranted = permissionsMap.values.reduce { acc, next -> acc && next }if (areGranted) {Toast.makeText(context, "Permission Granted", Toast.LENGTH_SHORT).show()} else {Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()}}Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(12.dp)) {Button(onClick = {if(permissions.all {ContextCompat.checkSelfPermission(context,it) == PackageManager.PERMISSION_GRANTED}) {// Get the location} else {launcherMultiplePermissions.launch(permissions)}}) {Text(text = "Get Current Location")}}

使用accompanist permissions库

与第一种使用方法相比,使用accompanist permission库是一种更容易获得运行时权限的方法。在build.gradle文件中添加该库。

implementation "com.google.accompanist:accompanist-permissions:0.23.1"

添加依赖项后,需要使用rememberPermissionState()方法来维护我们传递给它的权限状态。同时使用PermissionRequired()来观察运行时的权限状态。它包含所有权限状态的视图,比如允许或拒绝的视图。

val permissionState = rememberPermissionState(permission = Manifest.permission.CAMERA)PermissionRequired(permissionState = permissionState,permissionNotGrantedContent = {Toast.makeText(context, "Permission not granted", Toast.LENGTH_SHORT).show()},permissionNotAvailableContent = {Toast.makeText(context, "Permission not available", Toast.LENGTH_SHORT).show()}) {if (isShowCamera) {cameraLauncher.launch(uri)isShowCamera = false}}

由于在这个示例中使用相机,需要创建相机启动器来从活动结果中捕获图像。

val cameraLauncher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) {isShowCamera = falsecapturedImageUri = uri}

现在我们已经完成了权限状态和相机启动器的设置。下一步是使用权限。点击任何按钮或操作时,我们需要调用permissionState.hasPermission来检查权限是否被授予。 如果没有被授予,我们需要调用权限状态启动器以显示运行时权限对话框。

Button(onClick = {if(permissionState.hasPermission) {cameraLauncher.launch(uri)} else {isShowCamera = truepermissionState.launchPermissionRequest()}
}) {Text(text = "Open Camera")
}

同样地,您可以使用Accompanist库请求多个权限。查看以下代码以获取使用Accompanist请求多个权限的示例。

val permissionsState = rememberMultiplePermissionsState(permissions = listOf(Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION)
)PermissionsRequired(
multiplePermissionsState = permissionsState,
permissionsNotGrantedContent = {Toast.makeText(context, "Permission not granted", Toast.LENGTH_SHORT).show()
},
permissionsNotAvailableContent = {Toast.makeText(context, "Permission not available", Toast.LENGTH_SHORT).show()
}) {//content}
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(12.dp)) {Button(onClick = {if(permissionsState.permissions.all {ContextCompat.checkSelfPermission(context,it.permission) == PackageManager.PERMISSION_GRANTED}) {// access location} else {permissionsState.launchMultiplePermissionRequest()}}) {Text(text = "Location Permission")}}

效果如下
demo effect

完整代码地址

https://github.com/velmurugan-murugesan/JetpackCompose/tree/master/RuntimePermissionJetpackCompose


http://www.ppmy.cn/news/168588.html

相关文章

图扑虚拟现实 VR 智慧办公室可视化

前言 “虚拟现实”是来自英文“Virtual Reality”&#xff0c;简称 VR 技术&#xff0c;其是通过利用计算机仿真系统模拟外界环境&#xff0c;主要模拟对象有环境、技能、传感设备和感知等&#xff0c;为用户提供多信息、三维动态、交互式的仿真体验。 效果展示 图扑软件基于…

linux0.12-12-2-buffer

基本上看完赵老师中文解释&#xff0c;都可以自己写这部分的代码。 [622页] 12-2 buffer.c程序 从本节起&#xff0c;我们对fs/目录下的程序逐一进行说明和注释。按照本章第2节中的描述&#xff0c; 本章的程序可以被分成4个部分&#xff1a; 高速缓冲管理&#xff1b; 文件…

电脑html连接电视无信号,康佳液晶电视与电脑连接后无信号输入怎么解决?

我猜测 你用的是液晶 电视 使用了 不正确的普通vga线路 电脑的输出也是vga线路 使用的分辨率 应该是1280 768 吧&#xff1f;刷新频率设置的60&#xff1f; 这种条件一定会频闪 我的也是 为了不闪 1 使用支持dvi或者hdmi接口的显示卡 板载显卡一律不来 2 使用高级dvi 或者hdmi线…

为什么特小尺寸液晶屏价格比较高

这段时间有几个客户咨询特别小尺寸&#xff08;比如1020mm或者更小尺寸&#xff09;的LCD液晶屏的时候都有疑问就是&#xff0c;如此特别小尺寸的液晶屏为什么价格反而比之前的稍大点尺寸&#xff08;比如2030mm&#xff09;的液晶屏价格还要贵呢&#xff1f; 首先我们从液晶屏…

液晶面板里面有些什么配件_液晶电视核心部件各类液晶面板介绍是什么?请生意经的朋友帮忙解答...

与有相当密切的关系,液晶面板的产量、优劣等多种因素都连系着液晶电视自身的质量、价格和市场走向。其中液晶面板关系着玩家最看重的响应时间、色彩、可视角度、对比度等参数。从液晶面板可以看出这款液晶电视的性能、质量如何。下面pjtime为大家介绍一下各类主流的液晶面板。v…

液晶电视服务器无响应时间,液晶响应时间不能决定一切

液晶响应时间不能决定一切 互联网 发布时间&#xff1a;2009-04-21 02:13:27 作者&#xff1a;佚名 我要评论 在去年这个时候&#xff0c;相信用户在购买液晶显示器时最看重的一项参数便是响应时间。自液晶显示器的响应时间达到 8ms之后&#xff0c;人们对液晶显示器的这…

电视投屏显示设置服务器,Win10怎么投屏到电视?WIN10投屏到液晶电视具体步骤...

现在液晶电视价格越来越便宜&#xff0c;很少的钱就可以买一台60寸以上的电视&#xff0c;那么使用电脑的朋友一定想要把画面投屏到电视上&#xff0c;用于玩游戏、看电影吧&#xff01;Win10就有非常好用的投屏功能&#xff0c;很多朋友可能不知道如何操作&#xff0c;这里小编…

液晶面板价格高涨,OLED电视或迎来春天

分析机构Omdia公布的数据指出2020年前11个月4K液晶面板价格就上涨了七成&#xff0c;估计今年一季度可望再上涨最高两成&#xff0c;这意味着液晶面板价格一年多时间上涨一倍多&#xff0c;液晶面板价格的持续上涨为OLED电视的发展提供了机会。 多种因素促使液晶面板价格上涨 2…