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

Android 11删除媒体文件报错:Uri需关联特定ID

问题

在Android 10及以上系统中,调用MediaStore.createDeleteRequest唤起用户确认删除媒体文件的窗口时,抛出异常:java.lang.IllegalArgumentException: All requested items must be referenced by specific ID,原因是传入的Uri格式不符合接口要求。

当前代码:

if (Build.VERSION.SDK_INT >= 30) {
    val collection: ArrayList<Uri> = ArrayList()

    for (i in 0 until Params.dataListPath.size) {
        collection.add(Params.dataListPath[i].file.path.toUri())
        Log.d(TAG, "onShowDialogConfirmDelete: " + collection[i].path)
    }

    val pendingIntent = MediaStore.createDeleteRequest(requireActivity().contentResolver, collection).intentSender

    startIntentSenderForResult(pendingIntent, 100, null, 0, 0, 0, null)
}

异常信息:

java.lang.IllegalArgumentException: All requested items must be referenced by specific ID
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
        at android.content.ContentProviderProxy.call(ContentProviderNative.java:732)
        at android.content.ContentResolver.call(ContentResolver.java:2433)
        at android.provider.MediaStore.createRequest(MediaStore.java:834)
        at android.provider.MediaStore.createDeleteRequest(MediaStore.java:997)
        at com.test.cleanerapp.duplicate_files.view.fragment.DuplicateFindFragment.onShowDialogConfirmDelete(DuplicateFindFragment.kt:119)
解决方案
  • 核心问题:直接通过文件路径转换的file://格式Uri,不是MediaStore认可的带唯一ID的内容Uri。createDeleteRequest要求传入的Uri必须是MediaStore中存储的、包含媒体文件ID的内容Uri(格式示例:content://media/external/images/media/123)。

  • 修正方案:

    1. 根据文件路径查询MediaStore,获取对应媒体文件的唯一ID。
    2. 用ID构建符合要求的内容Uri,替换原代码中直接转换路径的逻辑。

修正后的示例代码:

if (Build.VERSION.SDK_INT >= 30) {
    val collection = mutableListOf<Uri>()
    val contentResolver = requireActivity().contentResolver

    Params.dataListPath.forEach { item ->
        val filePath = item.file.path
        // 针对全类型媒体文件的查询Uri,也可根据类型用更具体的Uri(如图片用MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        val queryUri = MediaStore.Files.getContentUri("external")
        val projection = arrayOf(MediaStore.Files.FileColumns._ID)
        val selection = "${MediaStore.Files.FileColumns.DATA} = ?"
        val selectionArgs = arrayOf(filePath)

        contentResolver.query(queryUri, projection, selection, selectionArgs, null)?.use { cursor ->
            if (cursor.moveToFirst()) {
                val mediaId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
                // 构建带ID的合法内容Uri
                val validUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), mediaId)
                collection.add(validUri)
            }
        }
    }

    if (collection.isNotEmpty()) {
        val pendingIntent = MediaStore.createDeleteRequest(contentResolver, collection).intentSender
        startIntentSenderForResult(pendingIntent, 100, null, 0, 0, 0, null)
    }
}
  • 额外说明:
    • 针对图片、视频、音频等特定类型的媒体文件,使用对应类型的MediaStore Uri查询(如MediaStore.Video.Media.EXTERNAL_CONTENT_URI),能提升查询精准度和效率。
    • Android 11及以上系统中,通过MediaStore查询无需MANAGE_EXTERNAL_STORAGE权限,只要文件属于媒体库可识别的类型即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 03:16:06