如何使用Media Store API访问/WhatsApp/Media/.Statuses文件夹适配Android SDK 30及以上
Android 30+ 访问WhatsApp .Statuses文件夹实现方案
1. 权限配置(AndroidManifest.xml)
- SDK 30~32 需声明权限:
android.permission.READ_EXTERNAL_STORAGE - SDK >=33 需声明权限:
android.permission.READ_MEDIA_IMAGES、android.permission.READ_MEDIA_VIDEO - 无需申请
MANAGE_EXTERNAL_STORAGE权限,避免上架应用商店被驳回 - 应用启动时先动态申请对应版本的存储权限,用户授权后再执行查询逻辑
2. MediaStore核心查询逻辑
Android 30+ 无需直接访问/WhatsApp/Media/.Statuses物理路径,通过MediaStore.Files表过滤相对路径即可拿到所有状态文件:
// 定义查询需要返回的字段 val projection = arrayOf( MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME, MediaStore.Files.FileColumns.MIME_TYPE, MediaStore.Files.FileColumns.DATE_MODIFIED ) // 过滤规则:匹配普通WhatsApp和商业版WhatsApp的状态目录 val selection = "${MediaStore.Files.FileColumns.RELATIVE_PATH} LIKE ? OR ${MediaStore.Files.FileColumns.RELATIVE_PATH} LIKE ?" val selectionArgs = arrayOf( "%WhatsApp/Media/.Statuses%", "%WhatsApp Business/Media/.Statuses%" ) // 执行查询,按修改时间倒序排列 contentResolver.query( MediaStore.Files.getContentUri("external"), projection, selection, selectionArgs, "${MediaStore.Files.FileColumns.DATE_MODIFIED} DESC" )?.use { cursor -> val statusList = mutableListOf<StatusMedia>() while (cursor.moveToNext()) { val mediaId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)) val mediaName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME)) val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE)) // 生成可直接访问的Content Uri val contentUri = if (mimeType.startsWith("image")) { ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mediaId) } else { ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, mediaId) } statusList.add(StatusMedia(mediaName, mimeType, contentUri)) } }
3. 后续操作说明
- 拿到
contentUri后可直接加载到ImageView、VideoView中预览 - 需要保存状态时,直接通过
contentResolver.openInputStream(contentUri)拿到输入流,写入到应用专属目录或者公共DCIM/StatusSaver目录即可,无需额外权限
4. 兼容注意事项
- 不要使用
MediaStore.Images或MediaStore.Video单表查询,隐藏目录的媒体文件不会被收录到这两个表中,必须用MediaStore.Files表查询 - 部分区域版本的WhatsApp可能修改路径,可根据实际情况扩展
selectionArgs的匹配规则 - 若查询结果为空,先检查是否已拿到存储权限,以及用户的WhatsApp是否已经生成过状态文件
内容的提问来源于stack exchange,提问作者Ambreen Zubari
相关产品推荐
相关产品推荐

