Android - 如何使用新的存储访问框架将文件复制到外部 sd 卡

Posted

技术标签:

【中文标题】Android - 如何使用新的存储访问框架将文件复制到外部 sd 卡【英文标题】:Android - How to use new Storage Access Framework to copy files to external sd card 【发布时间】:2016-07-01 14:30:11 【问题描述】:

我正在我的应用程序中实现文件浏览器功能。我知道如何使用 ACTION_OPEN_DOCUMENT_TREE 意图获得外部 sd 卡的持久权限,以及如何使用 DocumentFile 类创建文件夹和删除文件/文件夹。

但是,我找不到将文件复制/移动到外部 sd 卡文件夹的方法。你能指出我正确的方向吗?

【问题讨论】:

“但是我找不到将文件复制/移动到外部 sd 卡文件夹的方法”——除了可能之外,您无权访问“外部 sd 卡文件夹”通过getExternalFilesDirs()(复数)和亲属。您是否打算使用存储访问框架来询问用户将内容复制到哪里?如果是这样,请使用 Java I/O 从源 Uri 中的 InputStream 复制到目标 UriOutputStream 如果我使用 Java 文件系统,我没有修改辅助 sd 卡的权限。示例:创建文件夹:(new File(path)).mkdir();不起作用,但通过 documentFile.createDirectory(name); 使用新的 SAF; (其中 documentFile 是使用 DocumentFile.fromTreeUri(context, treeUri) 创建的)确实有效。所以我正在寻找一种使用 DocumentsContract API 复制文件的方法。 正如我所指出的,为您的原件获取Uri,为您的预期副本获取Uri,在两者上打开流,并执行 Java I/O。我不记得内置的复制或移动操作,至少在当前的 android 发布版本中是这样。 效果很好,谢谢! 【参考方案1】:

我已经在 SO 上使用了很多示例来解决这个问题。我的音乐文件解决方案:

     private String copyFile(String inputPath, String inputFile, Uri treeUri) 
    InputStream in = null;
    OutputStream out = null;
    String error = null;
    DocumentFile pickedDir = DocumentFile.fromTreeUri(getActivity(), treeUri);
    String extension = inputFile.substring(inputFile.lastIndexOf(".")+1,inputFile.length());

    try 
        DocumentFile newFile = pickedDir.createFile("audio/"+extension, inputFile);
        out = getActivity().getContentResolver().openOutputStream(newFile.getUri());
        in = new FileInputStream(inputPath + inputFile);

        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1) 
            out.write(buffer, 0, read);
        
        in.close();
        // write the output file (You have now copied the file)
        out.flush();
        out.close();

     catch (FileNotFoundException fnfe1) 
        error = fnfe1.getMessage();
     catch (Exception e) 
        error = e.getMessage();
    
    return error;

【讨论】:

inputPath 是 ??

以上是关于Android - 如何使用新的存储访问框架将文件复制到外部 sd 卡的主要内容,如果未能解决你的问题,请参考以下文章

如果 Android API 级别低于 26,如何将存储访问框架与 MediaMuxer 一起使用

在 Android 中使用存储访问框架保存文件

Android:从存储访问框架获得的 URI 中使用意图选择器打开文件

使用 SAF(存储访问框架)的 Android SD 卡写入权限

从URI获取真实路径,Android KitKat新的存储访问框架[重复]

如何在存储访问框架中设置不常见的文件扩展名?