You need to enable JavaScript to run this app. 如何从ActivityResultContracts返回的Content URI获取并解析CSV文件
优惠活动
大模型
产品
解决方案
定价
更多

如何从ActivityResultContracts返回的Content URI获取并解析CSV文件

从Content URI解析CSV的实现方案

由于Android 10+分区存储限制,不要尝试将Content URI转换为本地绝对路径,直接通过ContentResolver打开输入流读取内容是兼容所有版本的正确方案。

实现步骤

  • 通过ContentResolver打开选中CSV的输入流,利用Kotlin的use扩展自动管理流关闭,避免内存泄漏
  • 读取流内容,根据CSV的复杂程度选择自定义逐行解析或者第三方CSV解析库处理

代码示例

基础无依赖解析(适用于无转义的简单CSV)

直接在你现有回调的uri?.let块中填入以下逻辑:

uri?.let { csvUri ->
    contentResolver.openInputStream(csvUri)?.use { inputStream ->
        // 可根据CSV实际编码调整,Windows导出的CSV常为GBK编码
        val reader = InputStreamReader(inputStream, Charsets.UTF_8)
        val bufferedReader = BufferedReader(reader)
        val csvData = mutableListOf<List<String>>()
        
        bufferedReader.forEachLine { line ->
            // 简单CSV直接按逗号拆分,带引号/逗号的复杂场景不适用
            val rowCells = line.split(",")
            csvData.add(rowCells)
        }
        // csvData即为解析完成的二维数据,第一行通常为表头
    }
}

复杂CSV场景的处理说明

如果你的CSV包含带逗号的引号包裹单元格、单元格内换行这类复杂格式,直接按逗号拆分会出现解析错误,可以引入OpenCSV、Apache Commons CSV这类成熟解析库,直接将输入流传入解析器即可自动处理转义逻辑,示例代码逻辑:

// 在openInputStream返回的流的use块中
inputStream.bufferedReader().use { reader ->
    // 对应CSV解析库的读对象初始化
    val csvReader = CSVReader(reader)
    val allRows = csvReader.readAll() // 自动处理各类转义规则,直接拿到全量行数据
}

注意事项

  • 大文件处理:如果CSV体积较大,不要一次性把所有行加载到内存,用上述逐行读取的逻辑边读边处理业务,避免OOM
  • 编码适配:如果解析出现中文乱码,优先尝试把字符集换成Charset.forName("GBK"),适配Windows导出的CSV默认编码
  • 权限兼容:通过OpenDocument SAF返回的URI自带临时读权限,无需额外申请存储权限,完全适配分区存储规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 12:24:01