Android 权限申请现代化指南

一、核心概念:权限分类

Android 将权限分为三大类,申请方式各不相同:

  1. 普通权限 (Normal Permissions)
    · 范围:涉及应用沙盒外部但对用户隐私或设备操作风险极低的操作。
    · 示例:网络访问 (INTERNET)、振动 (VIBRATE)、设置壁纸 (SET_WALLPAPER)。
    · 授权方式:在 AndroidManifest.xml 中声明后,系统在安装时自动授予。
  2. 危险权限 (Dangerous Permissions)
    · 范围:涉及用户隐私或设备敏感数据的操作。
    · 示例:相机 (CAMERA)、精确位置 (ACCESS_FINE_LOCATION)、联系人 (READ_CONTACTS)、麦克风 (RECORD_AUDIO)。
    · 授权方式:必须在运行时明确向用户请求。这是本指南的重点。
  3. 特殊权限 (Special Permissions)
    · 范围:拥有系统级影响的极高特权权限。
    · 示例:在其他应用上方绘制 (SYSTEM_ALERT_WINDOW)、修改系统设置 (WRITE_SETTINGS)。
    · 授权方式:通常需要引导用户至系统特定页面进行授权,不通过标准 API 请求。

二、现代化实现方式

Google 推荐使用 Activity Result API 配合 ActivityResultContracts 来请求权限。这种方式取代了传统的重写 onRequestPermissionsResult() 的方法,具有以下优势:

· 生命周期安全:自动管理生命周期,避免内存泄漏。
· 代码清晰:请求逻辑和结果处理集中在一起,易于维护。
· 无需请求码:避免了手动管理 requestCode 的繁琐和错误。

  1. 声明权限

在 AndroidManifest.xml 中声明所有需要的权限,这是任何方式的前提。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><!-- 其他权限 --><application ...> ... </application>
</manifest>
  1. 请求单个权限(以相机权限为例)

在 Activity 或 Fragment 中:

class MainActivity : AppCompatActivity() {// 1. 注册权限请求启动器(Launcher)private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission() // 使用请求单个权限的合约) { isGranted: Boolean ->// 权限请求结果的回调handlePermissionResult(isGranted)}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val button = findViewById<Button>(R.id.btn_request)button.setOnClickListener {checkCameraPermission()}}private fun checkCameraPermission() {// 2. 检查权限是否已授予when {ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED -> {// 已有权限,执行操作openCamera()}// 3. 判断是否需要向用户解释原因shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) -> {showPermissionRationaleDialog()}else -> {// 直接发起请求(首次或用户未选择"不再询问")requestPermissionLauncher.launch(Manifest.permission.CAMERA)}}}private fun handlePermissionResult(isGranted: Boolean) {if (isGranted) {openCamera()} else {// 处理拒绝逻辑,特别是“不再询问”的情况showGoToSettingsDialog()}}private fun openCamera() {Toast.makeText(this, "Camera opened!", Toast.LENGTH_SHORT).show()}private fun showPermissionRationaleDialog() {AlertDialog.Builder(this).setTitle("Need Permission").setMessage("This app needs camera access to take pictures.").setPositiveButton("OK") { _, _ ->// 用户理解后,再次发起请求requestPermissionLauncher.launch(Manifest.permission.CAMERA)}.setNegativeButton("Cancel", null).show()}private fun showGoToSettingsDialog() {AlertDialog.Builder(this).setTitle("Permission Denied").setMessage("You have permanently denied this permission. Please enable it in app settings.").setPositiveButton("Open Settings") { _, _ ->// 跳转到本应用的系统设置页val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {data = Uri.fromParts("package", packageName, null)}startActivity(intent)}.setNegativeButton("Cancel", null).show()}
}
  1. 请求多个权限(同时请求相机和麦克风)

使用 RequestMultiplePermissions Contract。

class MainActivity : AppCompatActivity() {// 1. 注册多权限请求启动器private val requestMultiplePermissionsLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions: Map<String, Boolean> -> // 结果是一个映射表// 检查所有权限是否都被授予val allGranted = permissions.all { it.value }if (allGranted) {setupAppWithAllPermissions()} else {// 处理未全部授予的情况showSomePermissionsDenied()}}private fun requestMultiplePermissions() {// 2. 定义权限数组val permissionsToRequest = arrayOf(Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO)// 3. 发起请求requestMultiplePermissionsLauncher.launch(permissionsToRequest)}private fun setupAppWithAllPermissions() {Toast.makeText(this, "All permissions granted!", Toast.LENGTH_SHORT).show()}// ... 其他方法
}

三、最佳实践与关键提示

  1. 按需请求:在用户即将使用需要权限的功能时才请求权限,而不是一进入应用就请求所有权限。
  2. 善用解释 (shouldShowRequestPermissionRationale):
    · 此方法返回 true:用户之前拒绝过权限,你应该弹窗解释为什么需要它。
    · 返回 false:可能是第一次请求,或者用户已选择“不再询问”。
  3. 妥善处理“不再询问”:当用户勾选“不再询问”并拒绝后,再次调用 launch() 会直接拒绝。此时应引导用户前往系统设置手动开启权限。
  4. 测试所有路径:务必测试用户允许、拒绝、拒绝并不再询问等多种场景,确保应用行为正确。

通过遵循这套现代化方案,你的应用可以以一种用户友好、稳定且易于维护的方式处理Android运行时权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920730.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920730.shtml
英文地址,请注明出处:http://en.pswp.cn/news/920730.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大话 IOT 技术(3) -- MQTT篇

文章目录前言前情提要MQTT介绍组成万恶的appmqtt服务端伪代码实现开源的力量后话当你迷茫的时候&#xff0c;请点击 物联网目录大纲 快速查看前面的技术文章&#xff0c;相信你总能找到前行的方向 前言 本篇将开始讲述IOT技术的一个重点&#xff0c;mqtt协议。 我发现有一个…

大语言模型生成的“超龄劳动者权益保障制度系统化完善建议(修订版)”

大纲 │ ├── 一、基于征求意见稿现状的评估 │ ├── 制度意义&#xff1a;25条暂行规定首次明确权益范围&#xff0c;提供法律依据 │ └── 关键缺陷 │ ├── 法律定位不明确 │ ├── 社保衔接不足 │ └── 实施机制不完善 │ ├── 二、法…

【UnityAS】Unity Android Studio 联合开发快速入门:环境配置、AAR 集成与双向调用教程

这是一篇2021年的存档&#xff0c;使用Unity2020版本。 至今&#xff0c;Unity与AS很多通讯方式也是基于此衍生。 作为Unity与AS联合开发的受益者&#xff0c;难得掏出自己的饭碗&#xff0c;诸君共享&#xff01; Unity & Android Studio 联合开发快速入门 ——Unity与AS…

前后端联合实现多个文件上传

1、前端 Vue3CommonApplyBasicInfoForm.vue<script setup lang"ts" name"CommonApplyBasicInfoForm"> ...... // 文件输入实例对象 const fileInputRef ref<HTMLInputElement | null>(null); // 选择文件列表 const selectedFiles ref<Fi…

软考高级--系统架构设计师--综合知识真题解析

系列文章目录 文章目录系列文章目录一、2019年真题二、2020年真题三、2021年真题四、2022年真题总结一、2019年真题 二、2020年真题 三、2021年真题 四、2022年真题 总结

“帕萨特B5钳盘式制动器结构设计三维PROE模型7张CAD图纸PDF图“

摘 要本文首先对汽车制动器原理和对各种各样的制动器进行分析,详细地阐述了各类制动器的结构,工作原理和优缺点。再根据轿车的车型和结构选择了适合的方案。根据市场上同系列车型的车大多数是滑钳盘式制动器,而且滑动钳式盘式制动器结构简单,性能居中,设计规范,所以我选择滑动…

SQL注入6----(其他注入手法)

一.前言 本章节来介绍一下其他的注入手法&#xff0c;也就是非常规注入手法&#xff0c;来和大家介绍一下 二.加密注入 前端提交的有些数据是加密之后&#xff0c;到了后台在解密&#xff0c;然后再进行数据库查询等相关操作的&#xff0c;那么既然如 此我们也应该将注入语句…

visual studio2022 配置 PCL 1.13.1

PCL库下载 下载链接&#xff1a; https://github.com/PointCloudLibrary/pcl/releases 下载这两个。 PCL库安装 运行.exe文件进行安装。 环境变量勾第二个&#xff08;其实无所谓&#xff0c;反正还要添加别的环境变量&#xff0c;这里没选之后加也一样&#xff09;。 安装…

金融学-货币理论

前言 前面学习了什么是货币供给&#xff0c;货币供给的决定以及联邦储备体系在货币供给中所起的作用。现在我们要开始探讨经济中货币供给在决定价格水平与全部商品和劳务(总供给)中的作用。关于货币对经济影响的研究&#xff0c;称为货币理论(monetarythe-ory) 货币数量论 古典…

Visio绘图——给多边形增加连接线

每次在画项目框图和各类爪图的时候&#xff0c;连接线是最烦人的&#xff0c;虽然选择的是折线&#xff0c;单往往事与愿违。 下面就记录一下&#xff0c;如何查找各类连接线。 1、先展开左侧菜单栏&#xff0c;点击如下所示的“&#xff1e;”2、在展开的界面&#xff0c;再次…

【开题答辩全过程】以 付费自习室系统小程序为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

开疆智能Profinet转EtherCAT网关连接TR-Electronic传感器配置案例

本案例是通过开疆智能研发的Profinet转EtherCAT网关将传感器数据传送到PLC&#xff0c;由于两边设备采用协议不同&#xff0c;故而使用网关进行转换。网关配置&#xff1a;打开网关配置软件“EtherCAT Manager”并新建项目。根据不通网关型号也可选择ModbusTCP&#xff0c;Ethe…

VSCode中使用Markdown

文章目录1. 背景2. 安装插件3. 基础写作与预览4. 生成PDF文档5. 插入代码6. 插入图片7. 小结1. 背景 编程技术人员&#xff0c;很多人写作习惯用Markdown格式吧。 首先Markdown很简单&#xff0c;第二它的层次结构特别清晰&#xff0c;再然后它对嵌入图片、代码的支持很优秀。…

2024全栈技术栈选型指南

前后端技术栈选择现代前后端技术栈选择需兼顾市场需求与个人兴趣。前端领域React、Vue、Angular形成三足鼎立&#xff0c;React在大型项目占比达58%&#xff0c;Vue在小中型企业更受欢迎。TypeScript采用率年增长25%&#xff0c;已成为工程化标配。后端技术呈现多元化趋势&…

Spring Boot 项目文件上传安全与优化:OSS、MinIO、Nginx 分片上传实战

在实际的 Web 项目中&#xff0c;文件上传是一个常见需求&#xff1a;用户上传头像、企业后台上传资料、视频平台上传大文件等等。然而&#xff0c;文件上传也是最容易引发安全风险的功能之一&#xff0c;比如恶意脚本上传、木马文件伪装、存储空间消耗攻击。同时&#xff0c;当…

智能安防:以AI重塑安全新边界

传统安防依赖人力监控与简单报警&#xff0c;效率低下且易遗漏风险。随着人工智能、物联网及大数据技术的融合&#xff0c;智能安防正重新定义安全管理的范式&#xff0c;从被动响应转向主动预警&#xff0c;成为智慧城市与数字化生活的重要基石。智能安防的核心是人工智能视觉…

【AI】【强化学习】强化学习算法总结、资料汇总、个人理解

前言&#xff1a;自己学习西湖大学赵老师的课、youtube系列的课程相关比较重要的内容&#xff0c;后续不断再进行完善。 YouTube Serrano.academy rlhf讲的很好 合集最后一个没看 强化学习第四章 police没一步需要无穷&#xff0c;值迭代只需要一步 收敛不一样 值迭代:原因在于…

一键掌控三线资源:极简 Shell 脚本实现 CPU·磁盘·内存可视化巡检

目录 前言 数值型 for 循环 语法格式 示例&#xff1a;打印 1 到 5 示例&#xff1a;打印5次Hello World 示例&#xff1a;计算 1 到 100 的累加和 遍历型 for 循环 语法格式 示例&#xff1a;遍历字符串列表 示例&#xff1a;遍历数组 示例&#xff1a;遍历文件列表…

数据结构:创建堆(或者叫“堆化”,Heapify)

目录 最直观的思路 更优化的思路&#xff08;自底向上的构建&#xff09; 第一步&#xff1a;重新审视问题 第二步&#xff1a;找到规律&#xff0c;形成策略 用一个实例来推演 第三步&#xff1a;编写代码 总结与分析 我们来深入探讨“创建堆”&#xff08;或者叫“堆化…

基于 GPT-OSS 的成人自考口语评测 API 开发全记录

1️⃣ 需求与指标 在项目启动前&#xff0c;我们设定了核心指标&#xff1a; 字错率&#xff08;WER&#xff09;< 5%响应延迟 < 800 ms高可用、可扩展 这些指标将贯穿整个开发和测试流程。 2️⃣ 数据准备 准备训练数据是关键步骤&#xff0c;我们使用了 1k 条自考口…