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

Android11分区存储下调用moveDocument移动DocumentFile报无效URI错误

问题原因

该问题确实是Uri生成环节导致的。DocumentsContract.moveDocument 属于SAF框架下的接口,要求传入的所有Uri(源Uri、源父目录Uri、目标父目录Uri)都必须是SAF体系下的content://类型Uri,你通过DocumentFile.fromFile(outputFolder).getUri()得到的是file://开头的Uri,SAF的ContentProvider无法识别该类型的Uri,因此直接抛出IllegalArgumentException异常。

可行解决方案
  • 方案1:直接使用Java IO操作实现移动
    你目标目录是Context.getExternalMediaDirs返回的应用专属目录,本身已拥有读写权限,如果源DocumentFile对应的文件你也有直接读写权限,直接使用File的renameTo方法,或者先复制流再删除源文件实现移动,完全不需要调用SAF接口,兼容性最好。
  • 方案2:将目标目录转换为SAF认可的content://类型Uri
    因为目标目录处于外部媒体分区,你可以通过MediaStore查询对应路径的content:// Uri:
Uri targetContentUri = null;
Cursor cursor = getContentResolver().query(
    MediaStore.Files.getContentUri("external"),
    new String[]{MediaStore.Files.FileColumns._ID},
    MediaStore.Files.FileColumns.DATA + "=?",
    new String[]{outputFolder.getAbsolutePath()},
    null
);
if (cursor != null && cursor.moveToFirst()) {
    long id = cursor.getLong(0);
    targetContentUri = MediaStore.Files.getContentUri("external", id);
    cursor.close();
}

拿到targetContentUri之后再传入moveDocument方法即可。

  • 方案3:跨Document Provider场景的通用兼容方案
    moveDocument仅支持同一个文档提供方下的Uri移动,如果源文件Uri和目标Uri不属于同一个提供方,接口本身就不支持移动,此时直接打开源DocumentFile的输入流,在目标目录创建新文件写入流,写入完成后删除源文件,等效实现移动逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 09:45:03