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

如何在Intent.ACTION_OPEN_DOCUMENT_TREE选中的目录写入文件?

如何在选中的目录下写入文件?

嘿,我来帮你搞定这个问题!你已经通过ACTION_OPEN_DOCUMENT_TREE拿到了Tree URI,还转成了实际路径,现在要在这个路径下写文件对吧?这里有两种方法,我给你详细拆解:

方法一:直接用转换后的路径写入(注意权限限制)

如果你想直接用FileUtil.getFullPathFromTreeUri返回的路径操作,可以直接创建File对象,通过FileOutputStream写入内容。代码示例如下:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case FILE_CHOOSER_REQUEST_CODE:
            if (data != null) {
                String targetDirPath = FileUtil.getFullPathFromTreeUri(data.getData(), getActivity());
                // 在选中目录下创建要写入的目标文件,比如test.txt
                File targetFile = new File(targetDirPath, "test.txt");
                
                try (FileOutputStream fos = new FileOutputStream(targetFile)) {
                    // 写入自定义内容
                    String content = "这是要写入文件的内容";
                    fos.write(content.getBytes(StandardCharsets.UTF_8));
                    Toast.makeText(getActivity(), "文件写入成功", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(getActivity(), "写入失败,请检查权限", Toast.LENGTH_SHORT).show();
                }
                dismiss();
            }
            break;
    }
}

注意事项

这种方法在Android 10(API 29)及以上版本可能失效,因为分区存储政策限制了直接访问外部存储的文件路径。如果你的APP需要适配Android 10,可以在AndroidManifest.xml的<application>标签里添加android:requestLegacyExternalStorage="true"作为过渡方案,但Android 11及以上这个属性就不再起作用了,所以更推荐下面的官方合规方法。


方法二:直接用Tree URI操作(官方推荐,适配全版本)

其实不用转成路径也能操作,这是Android官方推荐的方式——ACTION_OPEN_DOCUMENT_TREE已经授予了你该目录的读写权限,用DocumentFile配合ContentResolver操作更安全,还能持久化权限,下次打开APP不用再让用户重复选择目录。代码示例:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case FILE_CHOOSER_REQUEST_CODE:
            if (data != null && data.getData() != null) {
                Uri treeUri = data.getData();
                
                // 可选:持久化权限,下次打开APP仍能访问该目录
                getActivity().getContentResolver().takePersistableUriPermission(
                    treeUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                );
                
                // 获取选中目录的DocumentFile对象
                DocumentFile selectedDir = DocumentFile.fromTreeUri(getActivity(), treeUri);
                if (selectedDir != null && selectedDir.isDirectory()) {
                    // 在目录下创建新文件,第一个参数是MIME类型,第二个是文件名
                    DocumentFile newFile = selectedDir.createFile("text/plain", "test.txt");
                    if (newFile != null) {
                        // 打开输出流写入内容
                        try (OutputStream outputStream = getActivity().getContentResolver().openOutputStream(newFile.getUri())) {
                            String content = "这是通过DocumentFile写入的内容";
                            outputStream.write(content.getBytes(StandardCharsets.UTF_8));
                            Toast.makeText(getActivity(), "文件写入成功", Toast.LENGTH_SHORT).show();
                        } catch (IOException e) {
                            e.printStackTrace();
                            Toast.makeText(getActivity(), "写入失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
                dismiss();
            }
            break;
    }
}

为什么推荐这个方法?

  • 完全适配Android 10+的分区存储政策,不会出现权限异常
  • 可以通过takePersistableUriPermission持久化权限,提升用户体验
  • 不需要依赖第三方工具类转换路径,减少潜在的兼容性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:15:12