当前位置: 首页 > article >正文

Android R11外部存储权限深度解析:MANAGE_EXTERNAL_STORAGE的实战应用与适配指南

1. Android R11外部存储权限的变革背景记得去年第一次在Android R11设备上测试文件管理器应用时突然发现原本运行正常的APK安装功能报错了。控制台里明晃晃的java.io.FileNotFoundException: /storage/emulated/0/Download/app.apk让我愣了半天——文件明明就在那里为什么读不到这就是Android R11存储权限改革给我们上的第一课。在Android 11API 30之前我们只需要在AndroidManifest.xml里声明WRITE_EXTERNAL_STORAGE权限用户授权后就能畅快地访问共享存储空间。但R11引入了**作用域存储Scoped Storage**的强化机制将应用能访问的范围严格限制在三个区域应用专属目录Context.getExternalFilesDir媒体集合MediaStore下载集合StorageAccessFramework这意味着像文件管理器这类需要广泛访问存储空间的应用突然变成了残障人士。我见过不少开发者试图用老方法申请WRITE_EXTERNAL_STORAGE权限结果发现只能操作图片、视频等媒体文件对APK、ZIP等非媒体文件束手无策。这种变化就像突然给所有应用戴上了特定颜色的眼镜只能看到特定类型的文件。2. MANAGE_EXTERNAL_STORAGE权限的定位解析2.1 权限的特殊性MANAGE_EXTERNAL_STORAGE是Google给特定类型应用开的后门但这个后门装了好几道安全锁。首先它属于特殊应用权限和WRITE_SETTINGS、SYSTEM_ALERT_WINDOW同级别需要用户手动在系统设置页授权。我在实际测试中发现即使用户同意了运行时弹窗的请求系统仍会跳转到专门的授权页面要求二次确认。这个权限的授权粒度也很特别——它不是传统的allow/deny二元选择而是表现为一个开关按钮。在小米设备上位于设置-应用管理-特殊权限管理-所有文件访问在原生Android上则是设置-应用和通知-特殊应用权限-所有文件访问。这种设计明显在暗示用户授予此权限的应用将获得非同寻常的能力。2.2 适用场景的边界根据我的踩坑经验不是所有应用都适合申请这个权限。Google Play的审核指南明确要求只有核心功能依赖广泛文件访问的应用才能使用比如文件管理器如Solid Explorer备份还原工具如钛备份杀毒软件如360安全卫士文档处理工具如WPS Office上架前需要提交权限使用声明表说明为什么必须使用该权限。我有次提交了一个天气应用结果被拒得毫无脾气——审查员直接反问天气预报需要读取所有APK文件吗3. 完整权限申请实战指南3.1 基础配置步骤首先在AndroidManifest.xml里声明权限注意这里和旧版本的区别uses-permission android:nameandroid.permission.MANAGE_EXTERNAL_STORAGE /然后需要添加权限使用声明。这是很多开发者容易漏掉的关键步骤会导致Google Play审核失败application ... uses-permission android:nameandroid.permission.MANAGE_EXTERNAL_STORAGE tools:ignoreScopedStorage / /application在代码中检查权限的状态要使用新的APIfun checkStoragePermission(): Boolean { return if (Build.VERSION.SDK_INT Build.VERSION_CODES.R) { Environment.isExternalStorageManager() } else { ContextCompat.checkSelfPermission( this, Manifest.permission.WRITE_EXTERNAL_STORAGE ) PackageManager.PERMISSION_GRANTED } }3.2 权限请求的最佳实践请求权限的代码需要处理多种情况。这是我优化过多次的实战代码private const val REQUEST_CODE 1024 fun requestStoragePermission() { when { Build.VERSION.SDK_INT Build.VERSION_CODES.R - { // 旧版本使用传统权限请求 requestPermissions( arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), REQUEST_CODE ) } Environment.isExternalStorageManager() - { // 已有权限 showToast(已获得所有文件访问权限) } else - { // 跳转系统设置页 try { val intent Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply { data Uri.parse(package:$packageName) } startActivityForResult(intent, REQUEST_CODE) } catch (e: Exception) { // 备用方案 val intent Intent().apply { action Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION } startActivityForResult(intent, REQUEST_CODE) } } } }这里有几个关键细节用try-catch包裹是因为不同厂商可能修改了权限页面的Intent action必须处理Android 11以下版本的兼容情况在onActivityResult中需要重新检查权限状态4. 适配过程中的常见陷阱4.1 权限弹窗的厂商定制问题在华为EMUI上测试时我发现即使用户在系统设置页授权后再次检查Environment.isExternalStorageManager()仍然返回false。后来发现是华为的权限管理机制有所不同需要额外处理fun isHuaweiPermissionGranted(): Boolean { return try { val manager getSystemService(content) as? ContentProviderClient manager?.call(getFileAccessMode, null, null)?.getInt(0) 1 } catch (e: Exception) { Environment.isExternalStorageManager() } }4.2 媒体文件的双重权限问题即使获得了MANAGE_EXTERNAL_STORAGE权限访问媒体文件时仍可能遇到问题。这是因为Android R11将媒体库访问和文件路径访问分离了。我的解决方案是fun getMediaFile(context: Context, uri: Uri): File? { return if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { // 使用MediaStore API val cursor context.contentResolver.query( uri, arrayOf(MediaStore.MediaColumns.DATA), null, null, null ) cursor?.use { if (it.moveToFirst()) { File(it.getString(0)) } else null } } else { // 直接使用文件路径 File(uri.path) } }4.3 权限被自动撤销的情况在OPPO ColorOS上我注意到当应用进入后台超过30分钟后MANAGE_EXTERNAL_STORAGE权限会被自动回收。这导致需要实现权限状态监听private val permissionObserver object : ContentObserver(Handler(Looper.getMainLooper())) { override fun onChange(selfChange: Boolean) { checkStoragePermission() } } override fun onStart() { super.onStart() contentResolver.registerContentObserver( Settings.Secure.getUriFor(all_files_access), false, permissionObserver ) }5. 替代方案评估与选择对于不适合申请MANAGE_EXTERNAL_STORAGE的应用可以考虑这些替代方案5.1 使用Storage Access Frameworkval intent Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply { flags Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION } startActivityForResult(intent, REQUEST_CODE)5.2 使用MediaStore APIval collection if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL) } else { MediaStore.Files.getContentUri(external) } val projection arrayOf( MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DISPLAY_NAME ) val query contentResolver.query( collection, projection, null, null, ${MediaStore.MediaColumns.DATE_ADDED} DESC )5.3 临时文件访问方案对于只需要一次性访问的场景val intent Intent(Intent.ACTION_GET_CONTENT).apply { type */* addCategory(Intent.CATEGORY_OPENABLE) } startActivityForResult(intent, REQUEST_CODE)在适配过程中我发现很多问题其实源于对Android存储体系的理解偏差。有次为了排查一个文件读取问题我花了三天时间才发现是因为没有正确处理content:// URIs和file:// URIs的转换。这让我深刻体会到在Android R11上处理文件访问就像在迷宫里找路——如果没有正确的权限钥匙再努力也是徒劳。

相关文章:

Android R11外部存储权限深度解析:MANAGE_EXTERNAL_STORAGE的实战应用与适配指南

1. Android R11外部存储权限的变革背景 记得去年第一次在Android R11设备上测试文件管理器应用时,突然发现原本运行正常的APK安装功能报错了。控制台里明晃晃的"java.io.FileNotFoundException: /storage/emulated/0/Download/app.apk"让我愣了半天——文…...

用华为eNSP模拟真实企业网:从VLAN划分到OSPF+NAT的保姆级配置实战

华为eNSP企业网络实战:从零搭建多部门互联的完整配置指南 当你第一次打开华为eNSP模拟器,面对空白的拓扑图和复杂的命令行界面时,是否感到无从下手?本文将带你一步步完成一个真实企业网络的搭建过程,涵盖VLAN划分、Tr…...

别再只装Ceph了!OpenStack T版原生对象存储Swift配置详解与性能初探

别再只装Ceph了!OpenStack T版原生对象存储Swift配置详解与性能初探 当我们在构建OpenStack私有云时,对象存储方案的选择往往成为技术决策的关键点。虽然Ceph因其强大的统一存储能力而广受欢迎,但OpenStack原生集成的Swift对象存储方案却常常…...

3步构建智能网络管控:OpenWrt访问控制插件实战指南

3步构建智能网络管控:OpenWrt访问控制插件实战指南 【免费下载链接】luci-access-control OpenWrt internet access scheduler 项目地址: https://gitcode.com/gh_mirrors/lu/luci-access-control 在现代家庭和企业网络中,设备管理已成为网络管理…...

Linux内核中的存储性能优化详解

Linux内核中的存储性能优化详解 引言 存储性能是Linux系统中的重要指标,它直接影响系统的I/O吞吐量、延迟和稳定性。Linux内核提供了丰富的存储性能优化机制,从文件系统到块设备,从内核参数到应用程序。本文将深入探讨Linux内核中的存储性能优…...

【每周分享】ADC芯片ADS1262测试记录总结和分享

最近使用ADC芯片ADS1262在做一些数据测试和调试,前前后后也测试了不少数据,今天就与大家分享一下测试记录的总结。一、 ADC芯片ADS1262的相关寄存器配置和数据测试记录 主要寄存器包括:1、POWER寄存器;2、INTERFACE寄存器&#…...

Qwen3-32B大模型推理实战:vLLM与Docker的高效本地部署指南

1. Qwen3-32B大模型简介与核心特性 Qwen3系列是当前开源大模型领域的重要选手,特别是32B参数的版本在性能和效率上达到了很好的平衡。这个"大家伙"不仅能处理常规的文本生成任务,还自带混合思维模式这种黑科技——简单说就是能根据任务类型自动…...

告别Windows系统管理烦恼:WinUtil一站式解决方案指南

告别Windows系统管理烦恼:WinUtil一站式解决方案指南 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 你是否曾为Windows系统管理而…...

胡桃工具箱终极指南:免费开源原神助手如何提升你的游戏体验

胡桃工具箱终极指南:免费开源原神助手如何提升你的游戏体验 【免费下载链接】Snap.Hutao 实用的开源多功能原神工具箱 🧰 / Multifunctional Open-Source Genshin Impact Toolkit 🧰 项目地址: https://gitcode.com/GitHub_Trending/sn/Sna…...

探索前沿技术趋势:2023年最值得关注的五大创新领域

1. 人工智能:从大模型到智能体的进化 2023年的人工智能领域正在经历一场范式转移。如果说前几年我们还在讨论单个模型的性能提升,现在整个行业已经转向多模态大模型和自主智能体的实战落地。我最近测试了几个主流开源模型,发现它们的推理能力…...

STM32F4 ADC初始化实战:从零开始配置模数转换器

1. STM32F4 ADC模块基础认知 第一次接触STM32F4的ADC功能时,我对着数据手册发呆了半小时——那些专业术语就像天书一样。后来在实际项目中摸爬滚打才发现,理解ADC其实可以很直观。想象ADC就是个"翻译官",把模拟世界的连续信号&…...

自动化测试框架搭建:Selenium + Pytest + Allure报告

自动化测试框架搭建:Selenium Pytest Allure报告 在当今快速迭代的软件开发周期中,自动化测试已成为保障产品质量的重要手段。Selenium作为主流的Web自动化测试工具,结合Pytest这一强大的Python测试框架,再辅以Allure生成的精美…...

MCU接口设计避坑:为什么你的上拉/下拉电阻总选不对?常见误区解析

MCU接口设计避坑:为什么你的上拉/下拉电阻总选不对?常见误区解析 在嵌入式硬件设计中,MCU的I/O接口电路看似简单,却暗藏玄机。许多工程师在项目调试阶段都会遇到信号不稳定、电平异常等问题,而这些问题往往源于上拉/下…...

别再只用GPT了!用这份电商客服数据集,5分钟本地微调你的专属行业大模型

5分钟打造电商专属AI客服:低成本微调实战指南 电商行业每天面对海量重复咨询——"我的快递到哪了?"、"商品能退换吗?"、"有没有优惠券?"。传统客服团队成本高昂,而通用大模型API不仅按量…...

ArcGIS Pro2.5深度学习环境配置避坑指南:从conda错误到网络问题全解析

ArcGIS Pro 2.5深度学习环境配置全流程实战指南 当你第一次打开ArcGIS Pro 2.5,准备大展身手进行深度学习分析时,可能会被复杂的Python环境配置过程浇了一盆冷水。别担心,这份指南将带你避开所有常见陷阱,从零开始搭建稳定的深度学…...

java8及java17核心特性

Java8核心特性速览✅ Lambda 表达式 - 函数式编程基础✅ 函数式接口 - FunctionalInterface 注解✅ 方法引用 - Class::method 语法✅ 默认/静态方法 - 接口可定义实现✅ Stream API - 声明式集合操作✅ 新日期时间 API - java.time 包(线程安全、不可变&#xff09…...

5大核心功能:LeagueAkari 本地自动化工具重塑你的英雄联盟游戏体验

5大核心功能:LeagueAkari 本地自动化工具重塑你的英雄联盟游戏体验 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit LeagueAkari 是…...

数学驱动自研:Deepoc 数学大模型支撑半导体全链路研发升级

面向半导体先进工艺与自主化发展需求,传统研发模式在精度、效率与成本上面临多重挑战。Deepoc 数学大模型以严谨数值计算、符号推理与全流程建模能力,为芯片设计、仿真、工艺、封测提供统一数学底层支撑,用系统化计算辅助产业研发决策&#x…...

遥感入门实战:用Python和Scikit-learn搞定PaviaU高光谱数据预处理(附完整代码)

遥感入门实战:用Python和Scikit-learn搞定PaviaU高光谱数据预处理(附完整代码) 高光谱遥感图像处理正逐渐成为环境监测、农业评估和城市规划等领域的重要工具。对于刚接触这一领域的技术人员来说,PaviaU数据集是一个理想的起点。本…...

Cursor-Free-VIP技术深度解析:AI编程助手限制突破的完全指南

Cursor-Free-VIP技术深度解析:AI编程助手限制突破的完全指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached yo…...

算法竞赛c++.新人每日一练.贪心算法(P1106删数问题 洛谷)

该题仍然是贪心思维,但是不能只思考删去最大的数字。如反例13245,做一次删数操作。删去最大的数得到1324,但删去3得到的数是1245.这是因为虽然删去的5是虽然是最大的数,但是3还在数字的高位上(就是百位)。所…...

SDRangel实战测评:主流SDR硬件性能对决与深度对比

SDRangel实战测评:主流SDR硬件性能对决与深度对比 【免费下载链接】sdrangel SDR Rx/Tx software for Airspy, Airspy HF, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay and FunCube 项目地址: https://gitcode.com/gh_mirrors/sd/sdrangel 在软件…...

Electron实战:从零构建跨平台桌面应用的全流程指南

1. 为什么选择Electron开发桌面应用? 第一次接触Electron是在2016年,当时团队需要快速开发一个跨平台的内部工具。尝试过QT、JavaFX等方案后,最终被Electron的"Web技术栈原生能力"的组合所吸引。用HTML写界面、用JavaScript调系统A…...

为什么选择Xtreme Download Manager:500%下载加速的终极解决方案

为什么选择Xtreme Download Manager:500%下载加速的终极解决方案 【免费下载链接】xdm Powerfull download accelerator and video downloader 项目地址: https://gitcode.com/gh_mirrors/xd/xdm 在当今数字时代,下载速度直接影响着我们的工作效率…...

PDFgear高效办公:10个必学技巧,大幅提升PDF处理效率

在日常办公与学习中,PDF已经成为最常用的文档格式之一。PDFgear作为一款免费、全能、轻量的PDF处理工具,集转换、编辑、OCR、压缩、加密等功能于一体,深受办公人群喜爱。但很多用户只用到基础功能,没有发挥它的真正效率。 今天给…...

用Activiti/Flowable跑一遍就懂了:BPMN2.0四种网关的Java代码与执行日志全解析

深入解析BPMN2.0四大网关:Activiti/Flowable实战与日志分析 在业务流程管理领域,BPMN2.0标准中的网关(Gateways)是控制流程走向的核心元素。本文将基于Spring Boot环境,通过Activiti/Flowable引擎的实际代码演示,结合执行日志和数…...

MT3201 普通 300/900ns 单线归零码三通道 LED 恒流驱动控制芯片

概述 MT3201 是单线归零码三通道 LED(发光二极管显示器)恒流驱动控制芯片,采用 300/900ns 单线归零码通讯协议。 MT3201 芯片内部集成有单线归零码数字接口、数据锁存器、LED 输出恒流驱动、内置 RC 振荡器、输出数据自动整形转发等电路。 MT…...

基于SpringBoot+Vue图书馆座位预约系统设计与实现+毕业论文+答辩PPT+指导搭建视频

开发工具: Idea或Eclipse数据库: MySQLJar包仓库: Maven前端框架: Vue2后端框架: Springboot具体请看视频演示源码已经过本人亲自测试,可完美运行...

高斯分布与拉普拉斯分布:从数学原理到Python实战

1. 高斯分布与拉普拉斯分布的核心数学原理 我第一次接触高斯分布是在大学物理实验课上,教授用它来描述测量误差。当时觉得这个"钟形曲线"特别神奇,后来才发现它无处不在——从考试成绩分布到股票价格波动。而拉普拉斯分布则是在研究金融数据时…...

终极指南:如何用ChemCrow AI助手在5分钟内完成复杂化学分析

终极指南:如何用ChemCrow AI助手在5分钟内完成复杂化学分析 【免费下载链接】chemcrow-public Chemcrow 项目地址: https://gitcode.com/gh_mirrors/ch/chemcrow-public ChemCrow是一个基于大语言模型的化学智能助手,通过整合12种专业化学工具&am…...