PhotoPicker:系统图片选择器 · AndroidX 源码指南
AAndroidX 源码指南
文件与分享
文件与分享 · androidx.documentfile

PhotoPicker:系统图片选择器DocumentFile 1.1.0-rc01

Activity Result API 选图、内嵌 PhotoPicker 与照片选择的最佳实践。

最后更新 2026-08-01

复制即用

用 Activity Result API 调起系统图片选择器(无需存储权限):

import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts

val pickMedia = rememberLauncherForActivityResult(
    ActivityResultContracts.PickVisualMedia()
) { uri ->
    // uri 为选中的图片 Uri,用户取消时为 null
    if (uri != null) {
        loadImage(uri)
    }
}

pickMedia.launch(
    PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
)

限定只选图片(不选视频):

PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)

内嵌 PhotoPicker(API 34+)

@OptIn(ExperimentalPhotoPickerComposeApi::class)
@Composable
fun EmbeddedPicker() {
    val state = rememberEmbeddedPhotoPickerState()
    EmbeddedPhotoPicker(state = state)
}

读取选中内容

// uri 是内容 URI,用 ContentResolver 读取
val input = context.contentResolver.openInputStream(uri)
val bytes = input?.readBytes()
input?.close()

媒体类型限定

请求说明
PickVisualMedia.ImageOnly只选图片
PickVisualMedia.VideoOnly只选视频
PickVisualMedia.ImageAndVideo图片或视频
MediaType("image/gif")指定 MIME 类型
MediaStore.MediaColumns.DATE_ADDED + 多重选择多选(PickMultipleVisualMedia
// 多选
val pickMultiple = rememberLauncherForActivityResult(
    ActivityResultContracts.PickMultipleVisualMedia(maxItems = 5)
) { uris -> uris.forEach { loadImage(it) } }

常见陷阱

  • 低版本无 Photo Picker:旧设备回退到 ACTION_OPEN_DOCUMENT 方案或系统旧选择器。
  • 读取权限:Photo Picker 返回的是临时授权内容 URI,读完后无需持久化权限,但长时间持有会失效。
  • 用户取消:uri 为 null,必须处理。
  • 大图 OOM:读取后按需缩放(BitmapFactory inSampleSize)。

要点

  • PickVisualMedia 走系统 Photo Picker,不需要 READ_MEDIA_IMAGES 等存储权限。
  • 返回值是 Uri(内容 URI),通过 contentResolver.openInputStream(uri) 读取。
  • 用户取消返回 null,需要处理空情况。
  • 内嵌 EmbeddedPhotoPicker 需要 API 34+(UPSIDE_DOWN_CAKE)且为实验 API,低版本回退到 Activity Result 方案。

相关页面