Android共享存储文本文件编辑失败,报ENOENT异常求助
问题分析
你遇到的核心问题是错误处理了Content Uri:
- 你保存到SharedPreferences的是
uri.path(/document/22949),这不是有效的文件路径,只是Content Uri的一部分。content://开头的Uri是文档提供者的统一资源标识,对应的不是本地文件系统的路径,无法用File类直接访问。 - 即使使用官方文档的方法,如果你传入的不是完整的
content://格式Uri,而是错误的path字符串,自然会找不到文件。
解决步骤
1. 修正Uri的保存逻辑
在获取到创建文件返回的Uri后,保存完整的Uri字符串而非path:
private val createDebugLogFileIntent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult? -> val uri = result?.data?.data val contentResolver = appContext().contentResolver val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION uri?.let { contentResolver.takePersistableUriPermission(it, takeFlags) // 保存完整Uri字符串到SharedPreferences val sp = appContext().getSharedPreferences("your_sp_name", Context.MODE_PRIVATE) sp.edit().putString("debug_log_uri", it.toString()).apply() } }
2. 读取并解析Uri
从SharedPreferences读取时,解析为合法的Uri对象:
// Java代码示例 SharedPreferences sp = getApplicationContext().getSharedPreferences("your_sp_name", Context.MODE_PRIVATE); String savedUriStr = sp.getString("debug_log_uri", null); if (savedUriStr != null) { Uri logUri = Uri.parse(savedUriStr); // 调用编辑方法 appendToLogFile(logUri, content); }
3. 正确的文件追加/编辑实现
注意官方示例用的是"w"模式(覆盖写入),如果需要追加内容,要使用"wa"模式。以下是追加内容的实现:
private void appendToLogFile(Uri uri, String content) { try { // 用"wa"模式打开,实现追加写入 ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "wa"); if (pfd == null) return; FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); // 写入内容 fileOutputStream.write(content.getBytes(StandardCharsets.UTF_8)); // 关闭流 fileOutputStream.close(); pfd.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
关键注意点
- 永远不要用
Uri.path作为文件路径使用,Content Uri的path字段不对应本地文件系统的真实路径。 - 必须保存完整的
content://格式Uri字符串,才能后续通过ContentResolver访问对应的文档。 - 持久化Uri权限(
takePersistableUriPermission)已经正确调用,确保应用重启后仍能访问该Uri。
内容的提问来源于stack exchange,提问作者Sagar Patel
相关产品推荐
相关产品推荐

