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

Android调用DocumentsContract.moveDocument()所需的authority是什么?

问题描述

在应用getExternalFilesDir对应目录或用户选定的文件夹下存放文件时,创建子文件夹后调用moveDocument()将父文件夹中的文件移动到新建子文件夹,操作失败。
Logcat输出报错如下:

W/DocumentsContract: Failed to move document
java.lang.IllegalArgumentException: Unknown authority 
    at android.content.ContentResolver.call(ContentResolver.java:2412)
    at android.provider.DocumentsContract.moveDocument(DocumentsContract.java:1520)

排查现象:对两个关联的DocumentFile调用.getUri().getAuthority()方法,返回值均为空字符串。
调用moveDocument的代码如下:

// file and subfolder are under the same parent
DocumentsContract.moveDocument(context.getContentResolver(),
                                    file.getUri(),
                                    subfolder.getParentFile().getUri(),
                                    subfolder.getUri());

补充说明:两个DocumentFile均真实存在,可正常在该子文件夹内创建文件,但无法将父文件夹下的目标文件移动到子目录中。
相关初始化代码与内部存储路径Uri如下:

// if user selected
DocumentFile dir       = DocumentFile.fromTreeUri(context, persistedUri);
// if 'internal'
DocumentFile dir       = DocumentFile.fromFile(getContext().getExternalFilesDir(null));
DocumentFile subfolder = dir.createDirectory(name);
DocumentFile file      = dir.createFile("video/mp4", vidname);

// Uris internal
file:///storage/emulated/0/Android/data/com.foo.bar/files/
file:///storage/emulated/0/Android/data/com.foo.bar/files/vid
file:///storage/emulated/0/Android/data/com.foo.bar/files/1656602728866.mp4
故障原因
  • DocumentsContract.moveDocument() 仅支持处理 DocumentsProvider 提供的 content:// 格式Uri,不支持file://开头的本地文件路径Uri。
  • 使用DocumentFile.fromFile()包装getExternalFilesDir()返回的普通文件路径生成的DocumentFile实例,对应Uri为file://开头,这类Uri没有authority字段,调用移动方法时会直接抛出Unknown authority异常。
  • 仅通过DocumentFile.fromTreeUri()获取的、基于用户SAF授权目录树生成的DocumentFile,才会返回带合法authority的content://Uri,可正常适配DocumentsContract系列操作接口。
修复方案

不要对所有来源的DocumentFile统一调用DocumentsContract.moveDocument(),按文件来源分场景处理:

  • 操作getExternalFilesDir等应用私有目录下的文件时,直接使用标准Java文件API完成移动,无需走SAF逻辑:
File source = new File(file.getUri().getPath());
File target = new File(subfolder.getUri().getPath(), source.getName());
source.renameTo(target);
  • 操作用户通过SAF选定的公共目录文件时,再调用DocumentsContract.moveDocument(),此时传入的Uri均为带合法authority的content://格式,可正常执行。
  • 通用适配逻辑:移动操作前先判断Uri的scheme,file开头走普通文件IO,content开头走SAF接口即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:27:20