El selector de fotos ofrece una interfaz de navegación que le presenta al usuario su biblioteca multimedia, ordenada por fecha (de lo más reciente a lo más antiguo). Como se muestra en el codelab de prácticas recomendadas sobre privacidad, el selector de fotos proporciona una forma integrada y segura para que los usuarios otorguen a tu app acceso solo a las imágenes y los videos seleccionados, en lugar de brindar acceso a su biblioteca multimedia completa.
Los usuarios que tengan proveedores de contenido multimedia en la nube aptos en sus dispositivos también pueden seleccionar fotos y videos almacenados de forma remota. Obtén más información sobre los proveedores de contenido multimedia en la nube.
La herramienta se actualizará automáticamente y ofrecerá una funcionalidad expandida a los usuarios de la app con el paso del tiempo, sin necesidad de realizar cambios en el código.
Cómo usar los contratos de actividad de Jetpack
Para simplificar la integración del selector de fotos, incluye la versión 1.7.0 o posterior de la biblioteca androidx.activity
.
Usa los siguientes contratos de resultados de actividad para iniciar el selector de fotos:
PickVisualMedia
(para seleccionar una sola imagen o video)PickMultipleVisualMedia
(para seleccionar varias imágenes o videos)
Si el selector de fotos no está disponible en un dispositivo, la biblioteca invoca automáticamente la acción de intent ACTION_OPEN_DOCUMENT
en su lugar. Este intent es compatible con dispositivos que ejecutan Android 4.4 (nivel de API 19) o versiones posteriores. Puedes verificar si el selector de fotos está disponible en un dispositivo determinado llamando a isPhotoPickerAvailable()
.
Cómo seleccionar un solo elemento multimedia
Para seleccionar un solo elemento multimedia, usa el contrato de resultados de la actividad PickVisualMedia
, como se muestra en el siguiente fragmento de código:
Objetos View
// 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)))
Vistas
// 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());
Compose
// Registers a photo picker activity launcher in single-select mode. val pickMedia = rememberLauncherForActivityResult(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)))
Cómo seleccionar varios elementos multimedia
Para elegir varios elementos multimedia, configura una cantidad máxima de archivos multimedia seleccionables, como se muestra en el siguiente fragmento de código.
Objetos View
// 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))
Vistas
// 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());
Compose
// 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 = rememberLauncherForActivityResult(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))
La plataforma limita la cantidad máxima de archivos que puedes pedirle al usuario que seleccione en el selector de fotos. Para acceder a este límite, llama a getPickImagesMaxLimit()
.
En dispositivos que no admiten el selector de fotos, se ignora este límite.
Disponibilidad de dispositivos
El selector de fotos está disponible en dispositivos que cumplen con los siguientes criterios:
- Ejecuta Android 11 (nivel de API 30) o una versión posterior.
- Recibe cambios en los componentes modulares del sistema con las actualizaciones del sistema de Google.
Los dispositivos más antiguos con Android 4.4 (nivel de API 19) a Android 10 (nivel de API 29) inclusive, así como los dispositivos Android Go con Android 11 o 12 compatibles con los Servicios de Google Play, pueden instalar una versión con portabilidad a versiones anteriores del selector de fotos. Para habilitar la instalación automática del módulo del selector de fotos con portabilidad a versiones anteriores a través de los Servicios de Google Play, agrega la siguiente entrada a la etiqueta <application>
en el archivo de manifiesto de tu app:
<!-- 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>
Cómo conservar el acceso a los archivos multimedia
De forma predeterminada, el sistema le otorga a tu app acceso a los archivos multimedia hasta que se reinicie el dispositivo o hasta que se detenga la app. Si tu app realiza trabajos de larga duración (por ejemplo, subir un archivo grande en segundo plano), es posible que necesites que este acceso se conserve durante un período más extenso. Para ello, llama al método 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);