Compose笔记(八)--权限
这一节主要了解一下Compose中权限的申请,其中主要用到accompanist-permissions这个权限库,它是一个简化的Android Compose 中权限管理的库,如下使用:
栗子:
依赖添加
dependencies {implementation("com.google.accompanist:accompanist-permissions:0.31.2-alpha")
}
单个权限
@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun PermissionExample() {val permissionState = rememberPermissionState(permission = Manifest.permission.CAMERA)Scaffold(topBar = {TopAppBar(title = { Text("Permission Apply Test") })}) {Column(Modifier.fillMaxSize(),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {when (permissionState.status) {PermissionStatus.Granted -> {Text("已经同意了相机权限")}is PermissionStatus.Denied -> {Column {val text = if (permissionState.status.shouldShowRationale) {"相机权限已拒绝,点击按钮再次请求"} else {"相机权限已被禁止"}Text(text = text)Button(onClick = {permissionState.launchPermissionRequest()}) {Text("点击获取权限")}}}}}}
}
多个权限
清单文件:<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.app.ActivityCompat
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionStatus
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.google.accompanist.permissions.rememberPermissionState
import com.google.accompanist.permissions.shouldShowRationale@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun MultiplePermissionsExample() {// 创建一个多权限状态对象,用于管理相机和存储权限val permissionsState = rememberMultiplePermissionsState(permissions = listOf(Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE))Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {val allPermissionsGranted = permissionsState.allPermissionsGrantedval shouldShowRationale = permissionsState.shouldShowRationaleif (allPermissionsGranted) {Text("所有权限已授予,可以使用相关功能。")} else {Column {if (shouldShowRationale) {Text("为了正常使用应用功能,请授予以下权限:相机、存储。")}Button(onClick = { permissionsState.launchMultiplePermissionRequest() }) {Text("请求权限")}}}}
}
注意:
1 依赖添加:确保在项目的 build.gradle(或 build.gradle.kts)文件中正确添加了 accompanist-permissions 库的依赖。同时,要注意使用与项目中其他 Compose 库版本兼容的 accompanist-permissions 版本,避免因版本不兼容导致编译错误或运行时异常。
2 注解使用:accompanist-permissions 库中的部分 API 被标记为 @ExperimentalPermissionsApi,这表示这些 API 还处于实验阶段,可能会在未来的版本中发生重大变化。在使用这些 API 时,需要在使用的函数或类上添加 @OptIn(ExperimentalPermissionsApi::class) 注解,以表明你已经了解并愿意承担使用实验性 API 的风险。
3 预先检查权限:在请求权限之前,应该先检查应用是否已经拥有该权限,避免不必要的权限请求对话框弹出,提升用户体验。可以使用 rememberPermissionState 或 rememberMultiplePermissionsState 返回的状态对象的相关属性进行检查。
原理
1. 基于 Android 系统的权限管理机制
Android 系统从 Android 6.0(API 级别 23)开始引入了运行时权限机制,应用需要在运行时请求某些危险权限。系统提供了一系列的 API 来处理权限请求,例如 ActivityCompat.requestPermissions 用于发起权限请求,ActivityCompat.checkSelfPermission 用于检查权限状态,ActivityCompat.shouldShowRequestPermissionRationale 用于判断是否需要向用户解释为什么需要该权限。
2 状态管理与响应式编程
Compose 是一种声明式的 UI 框架,它基于响应式编程模型,通过状态的变化来驱动 UI 的更新。accompanist-permissions 库利用了 Compose 的状态管理机制,将权限状态封装成可观察的状态对象,当权限状态发生变化时,自动触发 UI 的更新。
2.1 rememberPermissionState 和 rememberMultiplePermissionsState这两个函数是 accompanist-permissions 库的核心,用于创建权限状态对象。
rememberPermissionState:用于管理单个权限的状态。它返回一个 PermissionState 对象,该对象包含了权限的当前状态信息,如 hasPermission(权限是否已授予)、shouldShowRationale(是否需要显示权限请求说明)等。这些状态信息会随着权限请求结果的变化而自动更新,从而触发 Compose UI 的重组。
rememberMultiplePermissionsState:用于管理多个权限的状态。它返回一个 MultiplePermissionsState 对象,该对象可以跟踪多个权限的授予情况,通过 allPermissionsGranted 判断所有权限是否都已授予,通过 shouldShowRationale 判断是否有任何权限需要显示请求说明。
3. 权限请求处理
accompanist-permissions 库封装了权限请求的逻辑,通过 launchPermissionRequest 和 launchMultiplePermissionRequest 方法来发起权限请求。
3.1 内部实现
当调用 launchPermissionRequest 或 launchMultiplePermissionRequest 方法时,库会使用 Android 系统的 ActivityResultLauncher 来发起权限请求。ActivityResultLauncher 是 Android 系统提供的一种用于处理 Activity 结果的机制,它可以在请求权限后自动接收权限请求结果,并将结果传递给回调函数。
class PermissionStateImpl(private val permission: String,private val activity: ComponentActivity
) : PermissionState {private val _hasPermission = mutableStateOf(false)private val _shouldShowRationale = mutableStateOf(false)override val hasPermission: Booleanget() = _hasPermission.valueoverride val shouldShowRationale: Booleanget() = _shouldShowRationale.valueprivate val permissionLauncher = activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->_hasPermission.value = isGranted_shouldShowRationale.value = activity.shouldShowRequestPermissionRationale(permission)}override fun launchPermissionRequest() {permissionLauncher.launch(permission)}
}
4. 状态更新与 UI 重组
当权限请求结果返回时,accompanist-permissions 库会更新权限状态对象的状态信息。由于这些状态信息是使用 Compose 的 MutableState 封装的,当状态发生变化时,Compose 会自动检测到这些变化,并触发相关 UI 组件的重组,从而更新 UI 显示。例如,当用户授予相机权限后,cameraPermissionState.hasPermission 的值会从 false 变为 true,Compose 会重新执行 if (cameraPermissionState.hasPermission) 语句块,更新 UI 显示为 “相机权限已授予”。
相关文章:
Compose笔记(八)--权限
这一节主要了解一下Compose中权限的申请,其中主要用到accompanist-permissions这个权限库,它是一个简化的Android Compose 中权限管理的库,如下使用: 栗子: 依赖添加 dependencies {implementation("com.google.accompani…...
单例模式:确保一个类只有一个实例
目录 引言 1. 单例模式的核心思想 2. 单例模式的实现方式 2.1 饿汉式单例 2.2 懒汉式单例 2.3 线程安全的懒汉式单例 2.4 双重检查锁定(Double-Checked Locking) 2.5 静态内部类实现单例 2.6 枚举实现单例 3. 单例模式的使用场景 4. 单例模式…...

推荐一个好用的在线文本对比网站 - diffchecker
推荐网址:https://www.diffchecker.com UI设计也很不错,响应也很快,广告少 生成的对比还可以生成在线链接:(点击右上角“分享”) 可设置过期时间等 我生成的示例:https://www.diffchecker.c…...
学习第八十五行
[capture](parameters) -> return_type {// function body }capture: 捕获列表,指定如何捕获周围作用域中的变量。parameters: 参数列表,与普通函数类似。return_type: 返回类型,可以省略,编译器会自动推断。function body: 函…...

基于Django创建一个WEB后端框架(DjangoRestFramework+MySQL)流程
一、Django项目初始化 1.创建Django项目 Django-admin startproject 项目名 2.安装 djangorestframework pip install djangorestframework 解释: Django REST Framework (DRF) 是基于 Django 框架的一个强大的 Web API 框架,提供了多种工具和库来构建 RESTf…...

【Python 2D绘图】Matplotlib绘图(统计图表)
【Python 2D绘图】Matplotlib绘图(统计图表) 1. 概述1.1 简介1.2 安装1.3 导入1.4 保存1.5 数据来源1.5.1 Numpy ndarray1.5.2 Pandas DataFrame 1.6 中文显示 2. 基础样式2.1 颜色2.1.1 简称2.1.2 全称 2.2 布局2.2.1 Matplotlib 画布划分2.2.2 绘制子图…...
vue3框架的响应式依赖追踪机制
当存在一个响应式变量于视图中发生改变时会更新当前组件的所以视图显示,但是没有视图中不写这个响应式变量就就算修改该变量也不会修改视图,这是为什么?我们能否可以理解宽泛的理解为vue组件的更新就是视图的更新,单当视图中不存在…...
.Net 6 上传文件接口 文件大小报错整体配置
/// <summary>/// 上传文件/// </summary>/// <param name"file"></param>/// <returns></returns>[HttpPost("UploadifyFile")][RequestSizeLimit(2000 * 1024 * 1024)] // 设置最大请求体大小为 100MBpublic async …...

Git基础之工作原理
基础概念 git本地有三个工作区域,工作目录 Working Directory,暂存区Stage/Index和资源区Repository/Git Directory,如果在加上远程的git仓库就是四个工作区域 四个区域与文件交换的命令之间的关系 WorkSpace:工作区,就…...

小程序 wxml 语法 —— 41列表渲染 - 进阶用法
这一节讲解列表渲染的两个进阶用法: 如果需要对默认的变量名和下标进行修改,可以使用 wx:for-item 和 wx:for-item: 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…...
ElasticSearch 入门教程
ElasticSearch 入门教程 ElasticSearch 是一个分布式、可扩展的搜索和分析引擎,基于 Apache Lucene 构建,支持全文检索、结构化查询和聚合分析。本教程将带你深入了解 ElasticSearch 的核心概念、安装配置、常见操作,并提供示例代码…...

用Python写一个算24点的小程序
一、运行界面 二、显示答案——递归介绍 工作流程: 1. 基本情况:函数首先检查输入的数字列表 nums 的长度。如果列表中只剩下一个数字,它会判断这个数字是否接近 24(使用 abs(nums[0] - 24) < 1e-10 来处理浮点数精度问题&…...
分布式网络
分布式网络(Distributed Network)指的是一种计算机网络架构,其中计算资源(计算、存储、数据处理等)分布在多个物理或逻辑上的节点上,而不是集中在单一的服务器或数据中心中。这种架构的主要目标是提高系统的…...

忘记dedecms后台超级管理员账号和密码的解决方案
解决方案: 方案一、数据库修改: 1、前提是您能登录到数据库后台,登录MySQL数据库管理工具(如phpMyAdmin) 2、打开数据库中的 dede_admin 表,找到管理员记录,将 pwd 字段的值改成 f297a57a5a7…...

【Linux学习笔记】Linux基本指令分析和权限的概念
【Linux学习笔记】Linux基本指令分析和权限的概念 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】Linux基本指令分析和权限的概念前言一. 指令的分析1.1 alias 指令1.2 grep 指令1.3 zip/unzip 指…...

Git基础之分支
常用指令 git branch 列出本地所有分支 git branch -r 列出所有远程分支 git branch [branch-name] 新建一个分支,但依然停留在当前分支 git checkout -b [branch] 新建一个分支,并切换到该分支 git merge [branch] 合并指定分支当前分支 git branch -d …...
MAC电脑常用操作
环境:M3芯片 ,macOS15.2 🚀 快捷键 🖥️ 窗口管理 ✅ 退出/进入全屏模式 • 浏览器等应用:⌘ Command Ctrl F ✅ 最小化当前窗口 • ⌘ Command M • 💡 隐藏窗口但保留应用在后台运行 ✅ 关闭当前标…...

【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式
网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议: HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站,就是通过HTTP协议来…...

Springboot redis bitMap实现用户签到以及统计,保姆级教程
项目架构,这是作为demo展示使用: Redis config: package com.zy.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.Ob…...
【C++】:STL详解 —— 红黑树封装map和set
目录 红黑树的源代码 正向迭代器的代码 反向迭代器的代码 set的模拟实现 map的模拟实现 红黑树的源代码 #pragma once #include <iostream>using namespace std; // set ->key // map ->key/value// set ->key // map ->key/valueenum Colour {RED,BLAC…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...