照片选择器

照片选择器对话框中会显示设备上的媒体文件。您可选择要与应用分享的照片。
图 1. 照片选择器提供了一个直观的界面,便于与您的应用分享照片。

照片选择器的界面可供浏览和搜索,并按日期由进到早的顺序向用户呈现其媒体库中的文件。用户无需向应用授予对整个媒体库的访问权限,就可以通过该工具内置的功能安全选择图片和视频。

该工具会自动更新,让应用用户能够长期使用扩展的功能,而无需更改任何代码。

照片选择器适用于符合以下条件的设备:

添加支持库依赖项

如需使用照片选择器支持库,请添加版本 1.6.0 或更高版本的 androidx.activity 库。

该支持库使用以下 activity 结果协定来启动照片选择器:

如果照片选择器在设备上不可用,支持库会自动调用 ACTION_OPEN_DOCUMENT intent 操作。搭载 Android 4.4(API 级别 19)或更高版本的设备支持此 intent。您可以通过调用 isPhotoPickerAvailable() 来验证照片选择器在给定设备上是否可用。 如果您想自定义照片选择器的启动行为,也可以使用框架方法来检查照片选择器是否可用

选择单个媒体项

如需选择单个媒体项,请使用 PickVisualMedia activity 结果协定,如以下代码段所示:

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 allow the user to choose from.

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

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

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

// Launch the photo picker and allow the user to 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 allow the user to choose from.

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

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

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

// Launch the photo picker and allow the user to 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 allows the user to 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 allow the user to 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

// Registering Photo Picker activity launcher with multiple selects (5 max in this example)
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 allow the user to 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()。 在不支持照片选择器的设备上,系统会忽略此上限。

保留媒体文件访问权限

默认情况下,系统会授予应用对媒体文件的访问权限,直到设备重启或应用停止运行。如果您的应用执行长时间运行的工作(例如在后台上传大型文件),您可能需要将此访问权限保留更长时间。为此,请调用 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);

检查照片选择器是否可用

以下部分介绍了如何使用框架库来检查照片选择器在给定设备上是否可用。通过该工作流,您可以自定义照片选择器的启动行为,而无需依赖于支持库。

如需使用通过框架提供的照片选择器版本,请将以下逻辑添加到您的应用中:

Kotlin

import android.os.ext.SdkExtensions.getExtensionVersion

private fun isPhotoPickerAvailable(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        true
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        getExtensionVersion(Build.VERSION_CODES.R) >= 2
    } else {
        false
    }
}

fun handlePhotoPickerLaunch() {
    if (isPhotoPickerAvailable()) {
        // To launch the system photo picker, invoke an intent that includes the
        // ACTION_PICK_IMAGES action. Consider adding support for the
        // EXTRA_PICK_IMAGES_MAX intent extra.
    } else {
        // Consider implementing fallback functionality so that users can still
        // select images and videos.
    }
}

Java

import android.os.ext.SdkExtensions.getExtensionVersion;

private boolean isPhotoPickerAvailable() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        return true;
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        return getExtensionVersion(Build.VERSION_CODES.R) >= 2;
    } else
        return false;
    }
}

public void handlePhotoPickerLaunch() {
    if (isPhotoPickerAvailable()) {
        // To launch the system photo picker, invoke an intent that includes the
        // ACTION_PICK_IMAGES action. Consider adding support for the
        // EXTRA_PICK_IMAGES_MAX intent extra.
    } else {
        // Consider implementing fallback functionality so that users can still
        // select images and videos.
    }
}