Android 13下Google Photo Picker选媒顺序异常及带序号选择器需求
问题:Android 13下官方Photo Picker选择顺序错乱、视频丢失
我在Android发帖流程中实现多媒体选择功能,要求按用户选择的顺序压缩后展示。该功能在Android 12上正常运行,但在Android 13测试时,返回的媒体会按图片优先排序,还出现视频丢失的情况。目前使用Google官方的Photo Picker,求解决办法,或者推荐支持按选择顺序排列、能在媒体上显示序号标识的选择器库。
代码示例
val multiplePhotoPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickMultipleVisualMedia(5), onResult = { data -> if (data.isNotEmpty()) { compressedVideos.clear() selectedImage.apply { addAll(data) } coroutineScope.launch { for (i in data.indices) { val isImage = getMediaType( context, data[i] ) != MediaType.MediaTypeVideo compressedVideos.add( VideoItem( data[i], null, false, isImage, "", selectedMedias.size + i, data[i].length(context) ) ) Timber.tag("NoticeBoard").d("Item is Image ${isImage} is in postion ${i}") } val largeVideos = compressedVideos.filter { it.size > MAX_UPLOAD_SIZE }.map { VideoItem( it.currentPath, it.currentPath, it.isCompressed, it.isImage, it.itemId, it.index, it.size ) } compressedVideos.removeIf { it.size > MAX_UPLOAD_SIZE } val compressor = MediaCompressor(context) context.getActivity()?.let { isCompressing.value = true // 视频压缩方法 compressor.compressMultipleFiles( it, compressedVideos.filter { !it.isImage }.toMutableList(), callback = { videosItems -> // 图片压缩 val images = compressImages( compressedVideos.filter { it.isImage }.toMutableList(), context ) selectedMedias.addAll(images) selectedMedias.addAll(videosItems) selectedMedias.addAll(largeVideos) selectedMedias.sortBy { it?.index } isCompressing.value = false } ) } } } } )
一、修复官方Photo Picker的问题
1. 解决选择顺序错乱
Android 13的Photo Picker默认会对返回结果做图片优先的排序,可通过修改合约配置强制保留选择顺序:
val contract = ActivityResultContracts.PickMultipleVisualMedia(5).apply { setMediaType(VisualMediaType.ALL) // Android 13+ 明确设置选择模式为默认(保留选择顺序) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { setSelectionMode(ActivityResultContracts.PickMultipleVisualMedia.SelectionMode.DEFAULT) } }
2. 解决视频丢失问题
视频丢失通常和媒体类型过滤、Uri解析逻辑有关:
- 确保
VisualMediaType设置为ALL,不要只筛选图片; - 替换
getMediaType方法,改用系统ContentResolver解析媒体类型,避免Android 13下的解析错误:
fun isVideo(context: Context, uri: Uri): Boolean { val mimeType = context.contentResolver.getType(uri) return mimeType?.startsWith("video/") == true }
- 若代码中存在手动读取媒体文件的逻辑,需确认Android 13下已申请
READ_MEDIA_VIDEO权限。
二、替代选择器库推荐
如果官方库的问题无法彻底解决,推荐以下支持选择顺序、带序号标识的第三方库:
- PictureSelector:国内常用的多媒体选择器,默认保留选择顺序,支持自定义选中项的序号标识,兼容分区存储,自带图片视频压缩功能;
- Matisse:Square出品的轻量选择器,可配置保留选择顺序,通过自定义UI实现序号标识,支持多类型媒体混合选择;
- GalleryPicker:轻量级选择器,默认按选择顺序返回结果,自带选中状态标识,可快速扩展添加序号显示。
内容的提问来源于stack exchange,提问作者leomuko
相关产品推荐
相关产品推荐

