照片选择器

Photo picker dialog appears with media files on your device. Select a photo to share with the app.
图 1. 照片选择器提供了一个直观的 UI,用于与您的应用共享照片。

照片选择器提供了一个可浏览的界面,向用户展示其媒体库,并按日期从最新到最旧排序。如隐私最佳实践代码实验室所示,照片选择器提供了一种安全、内置的方式,供用户授予您的应用仅访问选定的图像和视频的权限,而不是其整个媒体库。

在设备上拥有合格的云媒体提供程序的用户也可以从远程存储的照片和视频中进行选择。了解有关云媒体提供程序的更多信息

该工具会自动更新,随着时间的推移为您的应用用户提供扩展的功能,而无需任何代码更改。

使用 Jetpack Activity 合同

为了简化照片选择器的集成,请包含版本 1.7.0 或更高版本的androidx.activity库。

使用以下活动结果合同启动照片选择器

如果设备上不可用照片选择器,则库会自动调用ACTION_OPEN_DOCUMENT intent 操作。此 intent 在运行 Android 4.4(API 级别 19)或更高版本的设备上受支持。您可以通过调用isPhotoPickerAvailable()来验证给定设备上是否可用照片选择器。

选择单个媒体项目

要选择单个媒体项目,请使用PickVisualMedia活动结果合同,如下面的代码片段所示

Kotlin

// Registers a photo picker activity launcher in single-select mode.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: $uri")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

// Launch the photo picker and let the user choose only images.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageOnly))

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.VideoOnly))

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
val mimeType = "image/gif"
pickMedia.launch(PickVisualMediaRequest(PickVisualMedia.SingleMimeType(mimeType)))

Java

// Registers a photo picker activity launcher in single-select mode.
ActivityResultLauncher<PickVisualMediaRequest> pickMedia =
        registerForActivityResult(new PickVisualMedia(), uri -> {
    // Callback is invoked after the user selects a media item or closes the
    // photo picker.
    if (uri != null) {
        Log.d("PhotoPicker", "Selected URI: " + uri);
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// Include only one of the following calls to launch(), depending on the types
// of media that you want to let the user choose from.

// Launch the photo picker and let the user choose images and videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only videos.
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.VideoOnly.INSTANCE)
        .build());

// Launch the photo picker and let the user choose only images/videos of a
// specific MIME type, such as GIFs.
String mimeType = "image/gif";
pickMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(new PickVisualMedia.SingleMimeType(mimeType))
        .build());

选择多个媒体项目

要选择多个媒体项目,请设置可选择媒体文件的最大数量,如下面的代码片段所示。

Kotlin

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
val pickMultipleMedia =
        registerForActivityResult(PickMultipleVisualMedia(5)) { uris ->
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (uris.isNotEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: ${uris.size}")
    } else {
        Log.d("PhotoPicker", "No media selected")
    }
}

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(PickVisualMediaRequest(PickVisualMedia.ImageAndVideo))

Java

// Registers a photo picker activity launcher in multi-select mode.
// In this example, the app lets the user select up to 5 media files.
ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
        registerForActivityResult(new PickMultipleVisualMedia(5), uris -> {
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (!uris.isEmpty()) {
        Log.d("PhotoPicker", "Number of items selected: " + uris.size());
    } else {
        Log.d("PhotoPicker", "No media selected");
    }
});

// For this example, launch the photo picker and let the user choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

平台限制了您可以在照片选择器中要求用户选择的最大文件数量。要访问此限制,请调用 getPickImagesMaxLimit()。在不支持照片选择器的设备上,此限制将被忽略。

设备可用性

照片选择器可在满足以下条件的设备上使用

运行 Android 4.4(API 级别 19)到 Android 10(API 级别 29)的旧版设备以及支持 Google Play 服务的运行 Android 11 或 12 的 Android Go 设备可以安装照片选择器的移植版本。要通过 Google Play 服务启用照片选择器模块的自动安装,请在应用清单文件的 <application> 标签中添加以下条目

<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
         android:enabled="false"
         android:exported="false"
         tools:ignore="MissingClass">
    <intent-filter>
        <action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
    </intent-filter>
    <meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>

持久化媒体文件访问

默认情况下,系统会授予您的应用访问媒体文件的权限,直到设备重启或您的应用停止。如果您的应用执行长时间运行的任务(例如在后台上传大型文件),则您可能需要将此访问权限持久化更长时间。为此,请调用 takePersistableUriPermission() 方法

Kotlin

val flag = Intent.FLAG_GRANT_READ_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, flag)

Java

int flag = Intent.FLAG_GRANT_READ_URI_PERMISSION;
context.contentResolver.takePersistableUriPermission(uri, flag);