Android API29、30开启requestLegacyExternalStorage=true删除文件触发RecoverableSecurityException
报错根因
- 首先是
requestLegacyExternalStorage配置的生效范围远没有你设想的广:- 该配置仅当应用的
targetSdkVersion <=29时,在Android 10(API29)系统上才能临时关闭作用域存储。只要你的应用targetSdkVersion >=30,哪怕安装在Android10的设备上,系统也会强制忽略这个配置,全程启用作用域存储规则 - 在Android11(API30)及以上的系统版本中,
requestLegacyExternalStorage参数本身就已经完全失效,系统不再提供“关闭作用域存储”的选项,旧版本里“无作用域存储时可直接删除其他应用媒体文件”的规则在这个版本之后已经不成立了
- 该配置仅当应用的
- 你当前要删除的是外部公共媒体库中、非你应用自身生成的视频文件(示例URI
content://media/external/video/media/23就是系统媒体索引里其他应用录入的公共文件),按照作用域存储的权限要求,应用没有这类文件的直接删除权限,直接调用contentResolver.delete()就会抛出RecoverableSecurityException——这个异常本身就是系统提供的可恢复权限入口,不是无法解决的硬故障。
适配的解决方案
- 覆盖API29到最新版本的通用单/批量删文件方案:
- 在执行删除操作时主动捕获
RecoverableSecurityException,从异常实例中提取系统内置的权限申请IntentSender - 将该
IntentSender传入系统的权限申请流程,触发系统自带的“是否允许删除所选文件”确认弹窗,用户手动确认授权后,重新执行删除逻辑即可完成操作,不需要申请额外的危险权限
- 在执行删除操作时主动捕获
- 文件管理类应用的批量全量删除方案:
如果你的应用属于官方认可的文件管理类工具范畴,可以申请MANAGE_EXTERNAL_STORAGE特殊权限,获取全量外部存储的管理权限后,就可以直接删除公共媒体库内的所有文件,不需要逐次弹出删除确认框 - 需要规避的无效操作:
- 不要仅依赖
requestLegacyExternalStorage配置适配高版本系统,targetSdk升级到30+后该配置完全不生效 - 不要尝试绕过MediaStore直接通过文件物理路径删除公共目录下的媒体文件,在API30+系统上这类操作会直接触发权限报错,同时也会被应用商店审核拦截。
- 不要仅依赖
你之前参考的官方文档中描述的旧权限规则,仅适用于应用targetSdkVersion <=28、完全未启用作用域存储的场景,当前主流上架应用的targetSdk基本都在33以上,这套旧逻辑已经无法适配线上的系统版本。
内容的提问来源于stack exchange,提问作者Himanshu
相关产品推荐
相关产品推荐

