You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android读取外部存储纯文本文件出现EACCES权限异常崩溃问题

根因说明
  • Android 10及以上版本启用了分区存储权限机制,即使申请了READ_EXTERNAL_STORAGE权限,也不允许应用直接通过绝对路径访问公共存储目录(比如Download、DCIM等)下的文件,这是你报EACCES权限拒绝的核心原因。
  • 你通过ACTION_OPEN_DOCUMENT唤起系统文件选择器选中文件后,得到的是content://类型的Uri,你截取Uri中的路径转成本地File对象访问的逻辑本身就是错误用法:系统通过Uri给你授予的是对应文件的临时访问权限,必须通过ContentResolver操作Uri来读写内容,不需要额外申请存储权限。
修复方案

推荐使用系统授权的Uri访问方案,不需要申请任何存储权限,兼容所有Android版本:

  1. 可以移除AndroidManifest.xml中的READ_EXTERNAL_STORAGE权限声明,以及MainActivity中所有和权限校验、请求相关的代码。
  2. 修改onActivityResult中的文件读取逻辑,直接通过ContentResolver读取Uri的输入流:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)

    if (requestCode == OPEN_DOCUMENT_REQUEST_CODE) {
        if (resultCode == Activity.RESULT_OK) {
            data?.data?.also { documentUri ->
                Log.v(TAG, "Document URI is $documentUri")
                // 直接通过ContentResolver打开Uri输入流读取内容
                contentResolver.openInputStream(documentUri)?.use { inputStream ->
                    val readContent = inputStream.bufferedReader().use { it.readText() }
                    Log.v(TAG, "Read content: $readContent")
                    outputText.text = readContent
                }
            }
        } else {
            Log.v(TAG, "onActivityResult resultCode is not OK=$resultCode")
        }
    } else {
        Log.v(TAG, "onActivityResult unknown requestCode=$requestCode")
    }
}

临时兼容方案(仅支持Android 10,不推荐)

如果你一定要用绝对路径访问文件,可以在AndroidManifest.xml的application标签中添加android:requestLegacyExternalStorage="true"属性,关闭分区存储的限制,这个配置在Android 11及以上版本会失效,不建议长期使用。

内容的提问来源于stack exchange,提问作者ArthurTheLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:36:07