如何使用Android Scoped Storage访问指定文件夹并写入文本文件
适配Android API 30+ 作用域存储TXT文件写入方案
前置配置
你需要先引入AndroidX DocumentFile库,在模块级build.gradle的dependencies块中添加如下依赖:
implementation "androidx.documentfile:documentfile:1.0.1"
实现步骤
1. 持久化目录访问权限
你在onActivityResult拿到用户选中的目录Uri后,需要先申请持久化权限,否则应用重启后权限会自动失效,无需用户重复选择目录:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) { if (requestCode == your-request-code && resultCode == Activity.RESULT_OK) { Uri dirUri = null; if (resultData != null) { dirUri = resultData.getData(); // 新增:持久化目录读写权限 final int takeFlags = resultData.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); getContentResolver().takePersistableUriPermission(dirUri, takeFlags); // 后续可将dirUri持久化到SharedPreferences,下次直接使用 } } }
2. 目录下创建TXT文件并写入数据
拿到合法的目录Uri后,通过DocumentFile操作创建文件,再通过ContentResolver打开输出流,即可使用BufferedWriter写入数据:
/** * 在用户选中的目录下创建TXT文件并写入内容 * @param dirUri 用户选中的目录Uri * @param fileName 要创建的txt文件名(如"gps_log_20240520.txt") * @param content 要写入的GPS数据内容 */ public void writeTxtToDir(Uri dirUri, String fileName, String content) throws IOException { // 1. 将目录Uri转为DocumentFile实例 DocumentFile dirDoc = DocumentFile.fromTreeUri(this, dirUri); if (dirDoc == null || !dirDoc.canWrite()) { throw new IOException("目录无写入权限"); } // 2. 在目标目录下创建txt文件,MIME类型设为text/plain DocumentFile fileDoc = dirDoc.createFile("text/plain", fileName); if (fileDoc == null) { throw new IOException("文件创建失败"); } Uri fileUri = fileDoc.getUri(); // 3. 打开输出流,用BufferedWriter写入数据 // 使用try-with-resources自动关闭流,无需手动释放 try (OutputStream outputStream = getContentResolver().openOutputStream(fileUri, "w"); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream))) { writer.write(content); writer.flush(); } }
常见注意事项
- 若需要追加写入已有文件,将
openOutputStream的第二个参数改为"wa"即可 - 若需要覆盖已存在的同名文件,可先调用
dirDoc.findFile(fileName)查找已有文件,存在则直接使用该文件的Uri写入,避免系统自动为同名文件添加(1)后缀 - 文件名不要包含路径分隔符
/等特殊字符,避免创建失败
内容的提问来源于stack exchange,提问作者Graziano
相关产品推荐
相关产品推荐

