直接回答
删除流程要先识别媒体行归谁所有,以及它属于哪个存储边界。Android 10 起,应用可在无需存储相关权限的情况下访问和修改自己创建的媒体;其他应用写入的共享 MediaStore 行遵循另一套 scoped-storage 流程。应用专属文件、MediaStore 项目 URI、Photo Picker 授权和普通 SAF 文档 URI 不能互换。不要把所有 Uri 都传给 MediaStore 请求:createDeleteRequest 与 createTrashRequest 要求目标是 MediaStore.AUTHORITY 下的媒体项目 URI。照片选择器的读取授权只赋予该入口明确说明的访问,不会自动成为写入或删除权限。 对于应用自有且不再需要的媒体行,可沿所有者路径删除,并单独清除应用拥有的缩略图、转录、嵌入或历史关联数据。Android 10 及以上,应用无需存储相关权限即可访问和修改自有媒体;但卸载重装后应重新核实当前所有权与访问状态,不能依赖旧安装的归属记录。其他应用创建行的 descriptor 可读不代表拥有权。target SDK 为 Android 11/API 30 及以上且不是默认图库的应用,修改或删除他人媒体时需要确认。MediaStore trash/delete 请求为指定项目 URI 提供系统确认 UI;它们不能删除云端、SAF、私有或任意 provider 数据。 移入垃圾箱和永久删除是两种不同选择。createTrashRequest(resolver, uris, true) 请求将指定 MediaStore 项目移入设备垃圾箱;用户批准后 Android 设置 IS_TRASHED。传 false 会请求对指定项设置相反状态,可用于将符合条件的项目移出垃圾箱。垃圾箱状态在系统定义的保留期结束前可恢复,不等于立即删除行。createDeleteRequest(resolver, uris) 则请求立即永久删除目标项,不先进入垃圾箱。用户界面和审计记录应明确标出用户选了哪种操作、包含哪些项目。 创建这些 API 返回 PendingIntent,不代表对象一创建操作就完成。应通过当前 Activity Result 流程启动 IntentSender,保存准确的 URI 集合标识并处理返回值。Android 明确说明,Activity result 到达前请求操作已经完成:删除获准后调用 ContentResolver.delete,移入垃圾箱则更新 IS_TRASHED。判断行缺失前,要确认当前查询权限,并在核验垃圾箱状态时设置适当可见范围,例如 QUERY_ARG_MATCH_TRASHED。查询失败、无权访问或意外缺行都应标为未知或外部变化,不能证明是本次删除造成。RESULT_OK 表示系统操作已完成,不应为“确保成功”再次执行相同删除。更新本地历史或数量前可重新查询;无法核验时应单独显示验证未知。 createWriteRequest 应与删除分开。它请求对指定媒体 URI 的一般写入访问,不等同于 trash 或 delete;不能只因应用想移除行就申请写入。读取权限也不是写入权限。target SDK 为 Android 11/API 30 及以上且不是默认图库的应用,修改或删除他人媒体时须显示确认,除非用户另获媒体管理特殊访问。target API 31+ 的应用可请求 MANAGE_MEDIA,但它范围更广,需要单独说明和系统设置流程。偶尔清理不应默认使用它;应优先采用更窄的具体项目请求。 IS_PENDING 不是垃圾箱标志。Android 用它保护应用正在写入的媒体项,直到创建者清除 pending 状态之前,其他应用无法看到它。这是应用自有行的写入/发布生命周期,不是将现有共享内容移入垃圾箱的用户请求。同样,删除 MediaStore 行不能证明应用私有缓存、模型输入、备份、导出或其他 provider 副本里的源像素也被清除。AI 应用拥有的派生项应走独立清理步骤,并单独报告成功情况。不能声称系统删除会擦除所有副本,也不能声称应用清缓存就删掉了用户的共享原件。 用可丢弃媒体测试每种边界和所有权。准备一条应用自有行、一条另一个测试应用创建的行、一条 Photo Picker URI 和一条 SAF URI。验证自有行删除与共享 MediaStore 同意流程不同,并确保非 MediaStore URI 不传给这些 API。覆盖批准移入垃圾箱、拒绝、批准恢复、批准永久删除、非成功结果、启动前项目消失,以及操作完成后的查询。系统操作结果和应用派生数据清理要分开核验。一次通过只支持所测系统/API、item authority、URI 列表和流程,不表示 Cove 当前向图库导出媒体或管理共享相册。
用户复核本地分析后想移除一张共享图库图片
Android 应用处理了一张从共享媒体中选择的照片。用户想把原图移入设备垃圾箱或永久删除,同时保留另行保存的文字笔记。应用可以读取该 URI,但这条媒体行不是应用创建的。
决策
先分类 URI 与所有权;对符合条件的 MediaStore 项目展示相应系统垃圾箱或删除请求,再重新查询结果,并按独立策略清理应用自己拥有的派生数据。
预期结果
用户能区分可恢复的垃圾箱状态与永久删除,也能看到外部媒体行是否改变,而不会把删除分析历史误当成删除原图或所有备份。
需要收集的证据
只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:
- ANDROID-MEDIASTORE-DELETE-CONSENT-2026-10:MediaStore API 30 的 trash/delete PendingIntent、确认结果和媒体行状态。
- ANDROID-PRIVACY-01:应用负责数据访问、存储、用户控制及用户可见的处理边界。
- Android 官方共享媒体与 MediaStore API 文档区分应用所有权、IS_TRASHED、永久删除、一般写授权及 MANAGE_MEDIA 特殊访问。
隐私声明需要数据清单和流量证据;“本地模型”标签本身不是证明。
实施流程
- 分类 URI 类型和当前所有权. 记录该项属于应用专属文件、应用自有 MediaStore 行、共享行、Photo Picker 还是其他 provider。卸载重装后重新核实所有权与访问状态;URI 可读或显示名称不能证明拥有权。
- 选择范围最窄的用户操作. 应用自有行通过所有者路径删除。对于合资格共享 MediaStore 行,明确选择移入垃圾箱或永久删除;只有任务确实需要写入时才请求写访问。
- 启动针对具体项目的系统请求. createTrashRequest/createDeleteRequest 只接收明确的 MediaStore 项 URI。通过当前 Activity Result 流程启动系统 PendingIntent,并保留操作标识。
- 处理结果并核对可见性. 记录 Activity result,确认查询范围,并指定适当垃圾箱可见性(需要时包含 QUERY_ARG_MATCH_TRASHED)。批准删除后,经核实的查询中目标行消失,与已完成操作一致。查询失败或意外缺行应记为未知/外部变化,不作独立删除证明;RESULT_OK 已表示操作完成,不得重复删除。
- 独立清除应用拥有的派生数据. 按另一份删除合同清理应用拥有的缓存、缩略图、转录或索引。如果用户选择保留独立文字笔记,不要因删除原图而一并移除。
让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。
验收标准
- 选择删除 API 前区分应用自有行、其他应用共享 MediaStore 行、Photo Picker 授权、SAF URI 和应用专属文件。
- trash、永久删除和一般写权限是不同动作;trash/delete 请求只接收 MediaStore authority 下的具体项目 URI。
- RESULT_OK 表示请求的系统操作已完成,不是仅获准的权限;验证还要检查查询访问权和正确的垃圾箱可见范围,无权查询或行缺失时仍标为未知。
- 不把读取权描述成删除权;拒绝、行缺失、备份或残余副本都不能变成虚假的删除成功承诺。
- 文章不声称 Cove 当前创建、导出、移入垃圾箱或管理共享媒体。
决策对照表
| 维度 | 选择或证据 | 解读方式 |
|---|---|---|
| 应用自有 MediaStore 项 | 按所有者路径删除,再清理关联的应用自有派生项。 | Android 10+ 允许创建者访问自己的媒体;不能从 URI 可读推导所有权。 |
| 将共享媒体移入垃圾箱 | 通过 createTrashRequest 请求 IS_TRASHED=true。 | 由系统确认且可恢复;之后系统按定义的保留期永久清除。 |
| 永久删除共享媒体 | 对准确项目 URI 调用 createDeleteRequest。 | 请求立即永久删除;它不是 trash 状态,也不是一般写入授权。 |
| SAF 或 Photo Picker URI | 遵守该入口及 provider 自身的访问和删除合同。 | 不能假定任意 provider URI 都能用于 MediaStore 请求。 |
需要避免的失败模式
- 把可读取 Photo Picker/SAF URI 等同于拥有对应 MediaStore 行的删除权限。
- 把 trash 的 IS_TRASHED 状态说成已经永久删除,或把 createWriteRequest 当成删除请求。
- 仅凭 RESULT_OK 或删除界面记录就声称应用缓存、导出、备份和其他副本都已消失。
还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。
最小复现记录
| 层级 | 记录内容 |
|---|---|
| 设备 | 厂商、型号、芯片、内存档位、操作系统版本 |
| 软件 | 应用版本和 Git 提交号 |
| 模型 | 系列、变体、版本、格式、文件长度、摘要、量化方式 |
| 运行时 | 名称、版本、请求后端及实际后端证据 |
| 工作负载 | 样例版本、输入摘要、提示词摘要、输出策略 |
| 结果 | 完成、失败、取消、回退及保护隐私的诊断信息 |
发布检查表
- ☐ 主要搜索问题已回答,且没有未经支持的数字。
- ☐ 所有模型文件和运行时版本均已固定。
- ☐ 代表性任务和失败处理策略均有说明。
- ☐ 生命周期、取消、清理和回退均已测试。
- ☐ 用户内容与网络边界均有说明。
- ☐ 结论只适用于被记录的配置。
- ☐ 新增测试结果时链接到原始方法或证据。
来源与相关证据
- Android privacy and security
- Android Developers — 从共享存储访问媒体文件
- Android API — MediaStore 删除、垃圾箱、写入请求与 URI 限制
- Android Developers — 应用专属存储与媒体所有权
- Android API — MediaColumns IS_TRASHED 与 IS_PENDING
中文部署与排错专题见。奇连 AI 端侧专题。
常见问题
Photo Picker 或 SAF 读取授权能让应用删除原图吗?
不能。读取授权和 MediaStore 行的所有权是两件事。只能使用该 provider 支持且用户明确授权的删除机制。
进入垃圾箱就表示媒体已经永久消失吗?
不是。createTrashRequest 获准后设置 MediaStore 垃圾箱状态;Android 说明系统会在定义的期限后永久删除其中项目。永久删除是另一种请求。
RESULT_OK 只表示系统批了权限吗?
不是。Android 说明删除或垃圾箱操作会在 Activity result 到达前完成,因此不能再重复调用。应在具备查询权限且指定正确垃圾箱可见范围后核验;查询不可用或意外缺行时应报告状态未知。
偶尔清理媒体也应该请求 MANAGE_MEDIA 吗?
不应默认这样做。它是面向符合条件且 target API 不低于 31 的应用的较广特殊访问。偶尔由用户发起的操作更适合针对具体项目的系统请求。