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

Android升级API后如何从文件选择器获取选中文件夹完整路径

问题原因

从Android 10(API 29)引入分区存储机制,Android 11(API 30)开始强制执行后,系统文件选择器返回的均为content://格式的Uri,不再直接暴露文件的真实磁盘路径。你之前通过:分割Uri路径获取真实路径的方法属于非官方的黑盒用法,本身就不具备版本兼容性,高版本系统自然失效。

你当前拿到的document/xxx是Content Provider的内部路径参数,和文件的实际存储路径没有任何关系,直接把这个路径传给File类当然无法得到正确结果。

解决方案

你当前的场景只需要给用户展示友好的路径提示,不需要真正拿到磁盘路径读写,所以直接使用系统提供的DocumentsContract API查询Uri对应的显示信息即可,完全符合官方规范,兼容性更好。

第一步:新增路径查询工具方法

fun getFriendlyDisplayPath(context: Context, uri: Uri): String? {
    // 处理content://类型的Uri
    if (ContentResolver.SCHEME_CONTENT == uri.scheme) {
        val projection = arrayOf(
            DocumentsContract.Document.COLUMN_DISPLAY_NAME,
            DocumentsContract.Document.COLUMN_RELATIVE_PATH
        )
        context.contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
            if (cursor.moveToFirst()) {
                val fileName = cursor.getString(cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DISPLAY_NAME))
                // API 26及以上支持获取相对路径,格式类似Downloads/myPicture/
                val relativePath = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    cursor.getString(cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_RELATIVE_PATH)) ?: ""
                } else {
                    ""
                }
                return relativePath + fileName
            }
        }
    }
    // 兼容旧版file://类型的Uri
    else if (ContentResolver.SCHEME_FILE == uri.scheme) {
        return uri.path
    }
    return null
}

第二步:替换原有路径获取逻辑

把你原来的路径处理代码:

val path = uri.path
if(path == null) {
    StaticStore.showShortMessage(this, getString(R.string.file_extract_semi).replace("_",file.name))
    return@registerForActivityResult
}
val f = File(path)
val p = f.absolutePath.split(":")[1]

替换为:

val p = getFriendlyDisplayPath(this, uri) ?: run {
    StaticStore.showShortMessage(this, getString(R.string.file_extract_semi).replace("_",file.name))
    return@registerForActivityResult
}
补充说明
  • 你当前的文件读写逻辑(通过ContentResolver.openFileDescriptor获取文件描述符读写)完全符合官方分区存储规范,不需要修改。
  • 如果确实有业务场景必须获取真实磁盘路径,需要申请MANAGE_EXTERNAL_STORAGE权限,但该权限仅允许文件管理、备份类等有强需求的应用上架谷歌商店,非必要不建议申请。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:51:03