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

Android API 34下如何从URI获取文件扩展名

解决Android API 34下无法获取文件扩展名的问题

你的核心问题在于用GetContent()获取的是内容Uri(格式类似content://xxx),而非直接的文件系统路径,直接通过File(it.path)获取文件信息在API34中完全不可靠——因为这类Uri的path字段根本不对应真实文件路径,甚至可能为空,自然拿不到扩展名。

以下是可行的解决方案:

方法1:通过MIME类型校验(推荐)

.db文件的标准MIME类型是application/x-sqlite3或application/vnd.sqlite3,通过ContentResolver获取Uri对应的MIME类型来判断,这比扩展名更可靠:

val launch = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
    uri?.let {
        val contentResolver = context.contentResolver
        // 获取MIME类型
        val mimeType = contentResolver.getType(it)
        // 校验MIME类型,同时兼容扩展名判断(应对部分自定义情况)
        val isDbFile = mimeType in setOf("application/x-sqlite3", "application/vnd.sqlite3") 
                || it.lastPathSegment?.endsWith(".db", ignoreCase = true) == true

        if (isDbFile) {
            coroutine.launch(Dispatchers.IO) {
                profileVM.load(it, context)
            }
        }
    }
}

方法2:从Uri路径片段提取扩展名

如果只需要通过扩展名判断,可以直接从Uri的最后一段路径提取:

val launch = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
    uri?.let {
        val fileName = it.lastPathSegment
        // 提取扩展名并转为小写,避免大小写问题
        val extension = fileName?.substringAfterLast('.', "")?.lowercase()
        if (extension == "db") {
            coroutine.launch(Dispatchers.IO) {
                profileVM.load(it, context)
            }
        }
    }
}

关键注意事项

  • 不要尝试通过Uri的path字段构建File对象,API34及更高版本的存储权限限制会直接阻止这种操作,且内容Uri本身不指向真实文件路径。
  • 确保你的profileVM.load()方法内部是通过ContentResolver.openInputStream(uri)来读取文件内容,而非直接访问File对象,这样才能符合Android的权限规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:22:24