Android 13照片选择器:如何让PickMultipleVisualMedia返回按选择顺序的URI?
解决Android 13照片选择器返回URI按选择顺序排序的问题
Android 13(API 33)的系统照片选择器默认返回的URI列表按媒体创建日期排序,而非用户选择顺序。默认的ActivityResultContracts.PickMultipleVisualMedia未支持保留选择顺序,但可以通过自定义ActivityResultContract利用系统提供的额外字段实现需求,无需自定义选择器。
实现步骤
- 自定义ActivityResultContract
系统照片选择器返回的Intent中携带MediaStore.EXTRA_PICK_ORDER字段,该字段存储了用户选择媒体的ID顺序列表。我们可以通过自定义Contract解析这个字段,重新构建按选择顺序排列的URI列表:
import android.app.Activity import android.content.Context import android.content.Intent import android.os.Build import android.provider.MediaStore import android.net.Uri import androidx.activity.result.contract.ActivityResultContract class PickMultipleVisualMediaWithOrder : ActivityResultContract<Int, List<Uri>?>() { override fun createIntent(context: Context, input: Int): Intent { return Intent(MediaStore.ACTION_PICK_IMAGES) .putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX_COUNT, input) } override fun parseResult(resultCode: Int, intent: Intent?): List<Uri>? { if (resultCode != Activity.RESULT_OK || intent == null) { return null } // 低于API 33时,系统默认返回选择顺序的URI列表 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { return intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM) } // 解析选择顺序的ID列表,构建对应URI val pickedIds = intent.getLongArrayExtra(MediaStore.EXTRA_PICK_ORDER) ?: return intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM) return pickedIds.map { mediaId -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon() .appendPath(mediaId.toString()) .build() } } }
- 在Jetpack Compose中使用自定义Contract
用自定义的Contract替代默认的PickMultipleVisualMedia,启动选择器后即可得到按用户选择顺序排列的URI列表:
import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.activity.result.contract.ActivityResultContracts @Composable fun ImagePickerDemo() { val pickImagesLauncher = rememberLauncherForActivityResult(PickMultipleVisualMediaWithOrder()) { uris -> uris?.let { orderedUris -> // 此处orderedUris为用户选择顺序的URI列表,处理你的业务逻辑 } } Column { Button(onClick = { // 传入最大选择数量,这里设为10 pickImagesLauncher.launch(10) }) { Text(text = "选择多张图片") } } }
注意事项
MediaStore.EXTRA_PICK_ORDER是API 33新增的字段,低版本系统无需额外处理,默认返回的URI列表即为选择顺序。- 若解析
EXTRA_PICK_ORDER失败,会降级返回默认的URI列表,保证兼容性。
内容的提问来源于stack exchange,提问作者Will Shepard
相关产品推荐
相关产品推荐

