Android 11+相册应用中如何用Kotlin获取回收站媒体列表
Android 11+ 相册应用回收站媒体获取与恢复实现
问题背景
已实现通过MediaStore.createTrashRequest将选中媒体移至系统回收站的功能,但原查询代码通过文件路径匹配.trashed无法获取回收站中的媒体项:
fun getHiddenMediaFiles(context: Context): List<String> { val hiddenMediaList = mutableListOf<String>() val contentResolver: ContentResolver = context.contentResolver val uri: Uri = MediaStore.Files.getContentUri("external") val projection = arrayOf( MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.DISPLAY_NAME ) val selection = "${MediaStore.Files.FileColumns.DATA} LIKE ?" val selectionArgs = arrayOf("%.trashed%") val cursor: Cursor? = contentResolver.query( uri, projection, selection, selectionArgs, null ) cursor?.use { val dataColumnIndex = it.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA) while (it.moveToNext()) { val filePath = it.getString(dataColumnIndex) hiddenMediaList.add(filePath) } } cursor?.close() for (ab in hiddenMediaList){ Log.e("data", "-----------size-----------------${hiddenMediaList.size}") } return hiddenMediaList }
解决方案
Android 11及以上版本中,系统回收站的媒体是通过MediaStore.MediaColumns.IS_TRASHED字段标记的(值为1表示已移入回收站),而非通过文件路径的.trashed标识。以下是正确的实现方式:
1. 查询回收站中的媒体项
data class TrashedMedia( val id: Long, val uri: Uri, val displayName: String, val mimeType: String ) fun getTrashedMedia(context: Context): List<TrashedMedia> { val trashedMediaList = mutableListOf<TrashedMedia>() val contentResolver = context.contentResolver // 可根据需求选择查询图片、视频或所有文件 val contentUri = MediaStore.Files.getContentUri("external") val projection = arrayOf( MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME, MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.MediaColumns.IS_TRASHED ) // 筛选条件:仅查询已移入回收站的媒体 val selection = "${MediaStore.MediaColumns.IS_TRASHED} = ?" val selectionArgs = arrayOf("1") contentResolver.query( contentUri, projection, selection, selectionArgs, "${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC" // 按修改时间倒序 )?.use { cursor -> val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID) val displayNameColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME) val mimeTypeColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE) while (cursor.moveToNext()) { val id = cursor.getLong(idColumn) val displayName = cursor.getString(displayNameColumn) val mimeType = cursor.getString(mimeTypeColumn) val uri = ContentUris.withAppendedId(contentUri, id) trashedMediaList.add(TrashedMedia(id, uri, displayName, mimeType)) } } return trashedMediaList }
2. 恢复回收站中的媒体项
和移入回收站的逻辑类似,使用MediaStore.createRestoreRequest触发系统权限弹窗,完成恢复操作:
fun restoreTrashedMedia(activity: Activity, mediaUris: List<Uri>) { try { val pendingIntent = MediaStore.createRestoreRequest( activity.contentResolver, mediaUris ) activity.startIntentSenderForResult( pendingIntent.intentSender, 102, // 自定义请求码 null, 0, 0, 0, null ) } catch (e: Exception) { e.printStackTrace() } }
注意事项
- 确保应用已申请
READ_EXTERNAL_STORAGE权限(Android 11+中访问媒体库需要此权限) - 若针对Android 13+,可使用更细化的
READ_MEDIA_IMAGES/READ_MEDIA_VIDEO权限替代READ_EXTERNAL_STORAGE - 查询时可分别使用
MediaStore.Images.Media.EXTERNAL_CONTENT_URI或MediaStore.Video.Media.EXTERNAL_CONTENT_URI来单独查询图片或视频,提升查询效率
内容的提问来源于stack exchange,提问作者Viral Radadiya
相关产品推荐
相关产品推荐

