You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Android TV 11及以上读取公共目录player.json权限解决方案咨询

Android TV 跨版本读取公共存储JSON文件的权限适配方案

针对读取/storage/emulated/0/Movies/app_name/db/player.json文件的需求,分版本给出适配方案,解决EACCES(Permission denied)异常:

Android 11+(含Android 13+)适配

Android 11+强制启用分区存储,禁止直接通过File类访问公共媒体目录,推荐两种方案:

方案1:通过MediaStore访问(无需特殊权限)

目标路径属于公共Movies目录,可通过MediaStore框架查询并读取文件,无需申请READ_EXTERNAL_STORAGEMANAGE_EXTERNAL_STORAGE

// 构建查询条件,匹配相对路径
val relativePath = "Movies/app_name/db/player.json"
val projection = arrayOf(MediaStore.Files.FileColumns._ID)
val selection = "${MediaStore.Files.FileColumns.RELATIVE_PATH} = ?"
val selectionArgs = arrayOf(relativePath)

contentResolver.query(
    MediaStore.Files.getContentUri("external"),
    projection,
    selection,
    selectionArgs,
    null
)?.use { cursor ->
    if (cursor.moveToFirst()) {
        val fileId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
        val fileUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), fileId)
        // 获取输入流读取JSON
        contentResolver.openInputStream(fileUri)?.use { inputStream ->
            val jsonContent = inputStream.bufferedReader().readText()
            // 处理JSON逻辑
        }
    }
}

方案2:迁移到应用专属存储(最优解)

如果该JSON文件是你的应用写入的,建议迁移到应用专属的Movies目录:

// 获取应用专属Movies目录路径
val appMoviesDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES)
val targetFile = File(appMoviesDir, "app_name/db/player.json")
// 直接读取,无需任何权限
val jsonContent = targetFile.bufferedReader().readText()

此路径属于应用私有区域,系统自动授权访问,符合Android隐私规范。

Android 10 替代权限方案

Android 10默认启用分区存储,无需申请MANAGE_EXTERNAL_STORAGE(该权限仅用于特殊场景),推荐兼容模式:

  1. AndroidManifest.xml中添加兼容标记:
<application
    ...
    android:requestLegacyExternalStorage="true">
</application>
  1. 动态申请READ_EXTERNAL_STORAGE权限,授权后即可通过File类直接访问目标路径,和Android 9及以下逻辑一致。

异常排查要点

  • 确认路径拼写:Android文件系统区分大小写,确保是Movies而非movies
  • 权限申请:运行时必须动态申请对应权限,且用户已授权
  • Android 11+禁止File类直接访问公共目录,必须用MediaStore或SAF(存储访问框架)
  • 若文件由其他应用写入,需确保文件权限为全局可读,或通过SAF让用户手动选择文件

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

火山引擎 最新活动