Android 11 Java开发基于Scoped Storage读取CSV文件报错解决方案
Android 11 分区存储下Java读取.csv文件问题说明及解决方案
问题背景
Android 11的Scoped Storage(分区存储)新机制学习成本较高,当前使用Java开发的开发者可参考的Android 11相关Java教程资源较少。
开发需求
应用需要打开.csv文件读取内容,存入arrayList后展示到textview中,对照官方文档操作始终无法落地。
初始代码实现
打开文件选择器逻辑
private void openFile() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("*/*"); intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, true); startActivityForResult(intent, PICKFILE_REQUEST_CODE); }
上述代码可正常唤起filepicker跳转至文件目录。
初始读取.csv文件逻辑
if (requestCode == PICKFILE_REQUEST_CODE && resultCode == Activity.RESULT_OK) { Uri uri = null; if (data != null) { uri = data.getData(); try { CSVReader reader = new CSVReader(new FileReader(uri.toString())); String[] nextLine; while ((nextLine = reader.readNext()) != null) { System.out.println(nextLine[0] + nextLine[1] + "etc..."); } } catch (IOException | CsvValidationException e) { Toast.makeText(this, e.toString(), Toast.LENGTH_SHORT).show(); } } }
报错信息
"java.io.FileNotFoundException:
content:/com.android.providers.media.documents/document/document%3A4165:
open failed: ENOENT (No such file or directory)"
已配置权限
Manifest文件中已提前添加如下权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
最终可用解决方案
if (requestCode == 1 && resultCode == Activity.RESULT_OK) { Uri uri = null; if (data != null) { uri = data.getData(); try { myList.clear(); InputStream inputStream = getContentResolver().openInputStream(uri); BufferedReader r = new BufferedReader(new InputStreamReader(inputStream)); String mLine; while ((mLine = r.readLine()) != null) { myList.add(mLine); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } reload_myList(); } }
适用限制
该方案仅适配仅含单列数据的CSV文件,直接调用readLine()即可满足需求;如果使用的是逗号分隔的多列CSV文件,不建议直接使用该方案,可能无法得到预期结果,可在读取文件时添加逗号正则匹配逻辑处理多列数据。
核心实现代码
InputStream inputStream = getContentResolver().openInputStream(uri); BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
内容的提问来源于stack exchange,提问作者Igor Lima
相关产品推荐
相关产品推荐

