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

求助:在Kotlin Jetpack Compose中使用rememberLauncherForActivityResult读取文件时出现文件不存在错误

问题分析与解决方案

嘿,这个问题我之前踩过坑!你出错的核心原因是把content URI当成了本地文件路径来处理——这是Android存储访问框架(SAF)里非常常见的误区。

为什么会报错?

当你用Intent.ACTION_OPEN_DOCUMENT选择文件时,系统返回的uri是content://开头的内容URI,这是Android内容提供者(Content Provider)对外暴露的文件访问入口,并不是直接的本地文件系统路径。你直接把它传给File(uri),系统自然找不到对应的文件,因为这个“路径”在本地文件系统里根本不存在,所以才会抛出ENOENT (No such file or directory)错误。

正确的处理方式

要读取这个URI对应的文件内容,你需要通过ContentResolver来打开输入流,而不是直接操作File。下面是修改后的完整代码:

@Composable
private fun Screen() {
    val context = LocalContext.current
    val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { result ->
        val uri = result.data?.data
        uri?.let { contentUri ->
            // 使用ContentResolver打开输入流读取文件,异步执行避免阻塞主线程
            lifecycleScope.launch {
                try {
                    context.contentResolver.openInputStream(contentUri)?.use { inputStream ->
                        val bytes = inputStream.readBytes()
                        println("文件读取完成,字节数:${bytes.size}")
                    }
                } catch (e: IOException) {
                    e.printStackTrace()
                    // 这里可以添加用户友好的错误提示,比如Toast
                }
            }
        }
    }
    Column() {
        Button(onClick = {
            val intent = Intent().setType("*/*").setAction(Intent.ACTION_OPEN_DOCUMENT)
            launcher.launch(intent)
        }) {
            Text("Open file")
        }
    }
}

额外注意点

  • 我添加了lifecycleScope.launch来异步读取文件,避免读取大文件时阻塞UI主线程(会导致ANR)。
  • 使用use函数自动关闭输入流,避免出现资源泄漏问题。
  • 增加了异常捕获逻辑,能处理用户取消选择、文件已被删除等异常场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:47:40