Android 11 Scoped Storage权限问题:如何访问指定子文件夹
Android 11 Scoped Storage:访问WhatsApp状态文件夹失败的解决方法
直接拼接Tree URI的方式在Scoped Storage机制下是无效的,系统不会认可手动构造的未授权URI。正确做法是通过DocumentFile的API从已授权的根目录(Media文件夹)逐级遍历获取子目录,具体实现如下:
错误原因
你之前尝试的Uri.parse(uri+"%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses")属于手动拼接URI,这种方式生成的URI未经过系统权限验证,无法被Scoped Storage认可,自然无法访问目标文件夹。
正确实现代码
// 从SharedPreferences获取保存的Media文件夹持久权限URI val savedUriString = requireContext().getSharedPreferences("status", MODE_PRIVATE).getString("uri", null) savedUriString?.let { uriStr -> val mediaTreeUri = Uri.parse(uriStr) // 从已授权的Media文件夹获取根DocumentFile val mediaRootDir = DocumentFile.fromTreeUri(requireContext(), mediaTreeUri) // 逐级获取子目录:com.whatsapp → WhatsApp → Media → .Statuses val waDir = mediaRootDir?.findFile("com.whatsapp") val waMediaDir = waDir?.findFile("WhatsApp")?.findFile("Media") val statusDir = waMediaDir?.findFile(".Statuses") // 验证目标文件夹是否存在并可访问 if (statusDir != null && statusDir.isDirectory) { // 在这里处理.Statuses文件夹内的文件,比如遍历文件 val statusFiles = statusDir.listFiles() // ... 后续业务逻辑 } else { // 文件夹不存在或无权限访问的处理 } }
关键注意事项
- 逐级遍历:必须通过
DocumentFile.findFile()方法依次获取每个子目录,确保每一步的目录都在已授权的权限范围内。 - 隐藏文件夹处理:
.Statuses是隐藏文件夹,findFile()方法可以正常识别,无需额外配置。 - 空值判断:每一步获取子目录时都要做非空判断,避免因路径不存在或权限问题导致空指针异常。
内容的提问来源于stack exchange,提问作者Muhammad Hamza
相关产品推荐
相关产品推荐

