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

Android 11下通过DocumentFile TreeUri更新MediaStore的DATE_MODIFIED失败如何解决

问题原因
  • 权限不匹配:通过Intent.ACTION_OPEN_DOCUMENT_TREE获取的SAF持久化权限,仅对SAF框架的文档操作生效,不直接授予MediaStore元数据的修改权限。MediaProvider修改DATE_MODIFIED时校验的是MediaStore专属修改权限,而非SAF权限。
  • IS_PENDING使用错误:IS_PENDING标记仅用于新媒体文件创建流程,作用是告知系统文件还在写入中暂不扫描。对已存在的文件修改该标记不符合设计逻辑,因此会出现返回false但文件被加pending前缀的异常表现。
  • 字段修改限制:Android 11及以上版本的MediaProvider默认禁止第三方应用直接修改非自身创建的媒体文件的DATE_MODIFIED字段,非文件所有者应用直接更新该字段会被直接拦截,对应你看到的W/MediaProvider: Ignoring mutation of date_modified警告。
解决方法

分两种场景处理:

场景1:待修改文件是你的应用创建的

你作为文件所有者可直接通过MediaStore更新,注意要把时间戳从毫秒转为秒(MediaStore存储的DATE_MODIFIED单位为秒,Java默认的System.currentTimeMillis()是毫秒单位,传错会被忽略):

ContentValues values = new ContentValues();
// 转成秒单位
values.put(MediaStore.MediaColumns.DATE_MODIFIED, newLastModified / 1000);
boolean success = context.getContentResolver().update(mediaUri, values,null, null) > 0;

场景2:待修改文件是其他应用创建的,仅持有SAF权限

不要直接操作MediaStore,通过SAF的DocumentsContract接口修改文件最后修改时间即可,系统会自动同步更新到MediaStore的DATE_MODIFIED字段:

boolean success = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    // 入参newLastModified为毫秒级时间戳,和Java常用时间格式兼容
    success = DocumentsContract.setLastModified(context.getContentResolver(), documentFile.getUri(), newLastModified);
}
// 修改成功后MediaStore会自动同步,无需额外操作
注意事项
  • 禁止对已存在的文件设置IS_PENDING标记,滥用会导致文件被加异常前缀,甚至被系统判定为未完成文件自动清理。
  • 如果修改后MediaStore没有及时同步,可手动触发媒体扫描更新元数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:27:00