升级Android API 33后读取共享Documents文件夹Excel文件权限被拒求助
解决API 33下读取公共Documents文件夹文件的权限问题
方案1:使用存储访问框架(SAF)读取文件
这是API 33及以后访问公共非媒体文件的官方推荐方案,具体实现步骤如下:
启动SAF选择目标文件或文件夹
若只需读取单个data.xlsx文件,使用ACTION_OPEN_DOCUMENT;若需要访问整个GRC文件夹,可改用ACTION_OPEN_DOCUMENT_TREE。示例代码:// 启动选择单个Excel文件的SAF界面 val openDocIntent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) // 指定Excel文件的MIME类型 type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" // 申请持久读取权限,避免重启后权限失效 flags = flags or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION } // 注册Activity结果回调 val docLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { result.data?.data?.let { fileUri -> // 持久化权限 contentResolver.takePersistableUriPermission(fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION) // 读取文件内容 processExcelFile(fileUri) } } } docLauncher.launch(openDocIntent)通过Uri读取Excel文件
利用ContentResolver获取文件输入流,替代原有的FileAPI操作:private fun processExcelFile(uri: Uri) { contentResolver.openInputStream(uri)?.use { inputStream -> // 这里替换为你常用的Excel解析逻辑(比如POI、EasyExcel) val workbook = XSSFWorkbook(inputStream) val targetSheet = workbook.getSheetAt(0) // 后续业务处理... workbook.close() } }
方案2:迁移文件到应用专属外部存储(仅适用于自身生成的文件)
如果data.xlsx是你的应用生成的,建议将文件迁移到应用专属的外部存储目录,该路径下的文件读写无需额外权限:
// 获取应用专属的Documents子目录 val appPrivateGrcDir = File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "GRC") // 创建目录(不存在则自动创建) appPrivateGrcDir.mkdirs() val targetExcel = File(appPrivateGrcDir, "data.xlsx") // 直接读写该文件即可,无需权限申请
关键说明
- API 33及以后,Google严格限制
MANAGE_EXTERNAL_STORAGE权限的使用范围,仅文件管理器等特定类型应用可申请,普通应用无法通过设置启用该权限,也无法上架Google Play。 READ_MEDIA_*系列权限仅针对图片、音频、视频等媒体文件,不覆盖文档类文件,因此无法用来读取Excel文件。
内容的提问来源于stack exchange,提问作者Milanor
相关产品推荐
相关产品推荐

