
Nessa interface, é possível navegar e fazer pesquisas. O usuário tem acesso à biblioteca de mídia, organizada da mais recente para a mais antiga. Conforme mostrado no codelab de práticas recomendadas de privacidade, o seletor de fotos oferece uma maneira segura e integrada para os usuários concederem ao app acesso apenas aos vídeos e imagens selecionados, e não à biblioteca de mídia inteira.
Os usuários que têm provedores de mídia em nuvem qualificados no dispositivo também podem selecionar fotos e vídeos armazenados remotamente. Saiba mais sobre provedores de mídia em nuvem.
A ferramenta é atualizada automaticamente, oferecendo mais funcionalidades aos usuários do app ao longo do tempo, sem exigir nenhuma mudança de código.
Usar contratos de atividade do Jetpack
Para simplificar a integração do seletor de fotos, inclua a versão 1.7.0 ou mais recente da
biblioteca androidx.activity
.
Use estes contratos de resultados da atividade para iniciar o seletor de fotos:
PickVisualMedia
, para selecionar um único vídeo ou imagem.PickMultipleVisualMedia
, para selecionar vários vídeos ou imagens.
Se o seletor de fotos não estiver disponível em um dispositivo, a biblioteca
vai invocar a
ação da intent
ACTION_OPEN_DOCUMENT
de forma automática. Essa intent oferece suporte a dispositivos que executam o Android 4.4
(nível 19 da API) ou versões mais recentes. É possível verificar se o seletor de fotos está disponível
em um determinado dispositivo chamando
isPhotoPickerAvailable()
.
Selecionar um único item de mídia
Para selecionar um único item de mídia, use o contrato de resultado da atividade
PickVisualMedia
, conforme mostrado no snippet de código abaixo:
Visualizações
// 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)))
Visualizações
// 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());
Escrever
// 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)))
Selecionar vários itens de mídia
Para selecionar vários itens de mídia, defina um número máximo de arquivos de mídia selecionáveis, conforme mostrado no snippet de código a seguir.
Visualizações
// 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))
Visualizações
// 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());
Escrever
// 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))
A plataforma limita o número máximo de arquivos que você pode pedir ao usuário
para selecionar no seletor de fotos. Para acessar esse limite, chame
getPickImagesMaxLimit()
.
Nos dispositivos sem suporte ao seletor de fotos, esse limite é ignorado.
Disponibilidade de dispositivos
O seletor de fotos está disponível em dispositivos que atendem a estes critérios:
- Executam o Android 11 (nível 30 da API) ou mais recente.
- Recebem mudanças nos componentes modulares do sistema pelas atualizações do sistema do Google.
É possível instalar uma versão de backport do seletor de fotos em dispositivos mais antigos com o Android 4.4 (nível 19 da API) ao Android 10 (nível 29 da API),
e também em dispositivos Android Go com o Android 11 ou 12 com suporte ao
Google Play Services. Para
ativar a instalação automática do módulo do seletor de fotos com backport pelo
Google Play Services, adicione a entrada abaixo à tag <application>
no
arquivo de manifesto do 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>
Manter o acesso ao arquivo de mídia
Por padrão, o sistema concede ao app acesso a arquivos de mídia até que o dispositivo seja
reiniciado ou até que o app seja interrompido. Se o app executar um trabalho de longa duração, como
o upload de um arquivo grande em segundo plano, talvez seja necessário que esse acesso persista por
um período mais longo. Para fazer isso, chame o
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);
Processar vídeos HDR com transcodificação
O Android 13 (API 33) introduziu a capacidade de capturar vídeos High Dynamic Range (HDR). Embora o HDR ofereça uma experiência visual mais rica, alguns apps mais antigos podem não estar equipados para lidar com esses formatos mais recentes, causando problemas como reprodução de cores não naturais (como rostos esverdeados). Para resolver essa incompatibilidade, o seletor de fotos oferece um recurso de transcodificação que pode converter automaticamente vídeos HDR para o formato intervalo dinâmico padrão (SDR) antes de disponibilizá-los ao app solicitante.
O objetivo principal da transcodificação do seletor de fotos é garantir uma experiência de mídia consistente e visualmente precisa em uma variedade maior de aplicativos, mesmo aqueles que ainda não têm suporte explícito a HDR. Ao transcodificar vídeos HDR para SDR, o seletor de fotos visa melhorar a compatibilidade de apps e oferecer uma experiência do usuário integrada.
Como funciona a transcodificação do seletor de fotos
A transcodificação HDR do seletor de fotos não está ativada por padrão. Para ativar esse recurso, seu app precisa declarar explicitamente os recursos de processamento de formato de mídia ao iniciar o seletor de fotos.
Seu app oferece recursos de processamento de mídia ao seletor de fotos. Isso é
feito ao iniciar o seletor de fotos usando a biblioteca de atividades do AndroidX, adicionando
mediaCapabilities
ao PickVisualMediaRequest.Builder
. Uma nova API, setMediaCapabilitiesForTranscoding(capabilities: MediaCapabilities?)
, foi adicionada ao PickVisualMediaRequest.Builder
para facilitar isso.
É possível controlar o comportamento da transcodificação HDR usando a classe MediaCapabilities
.
Forneça um objeto MediaCapabilities
especificando exatamente quais tipos de HDR seu app
aceita (por exemplo, TYPE_HLG10
, TYPE_HDR10
, TYPE_HDR10_PLUS
,
TYPE_DOLBY_VISION
).
Para desativar a transcodificação completamente, transmita null
para
MediaCapabilities
. Qualquer tipo de HDR não listado explicitamente nas
capacidades fornecidas será considerado incompatível. Essa API é compatível com o Android
13 (nível 33 da API) e versões mais recentes e é anotada com
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
.
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.annotation.RequiresApi
import android.os.Build
import android.util.Log
import android.provider.MediaStore
// Registers a photo picker activity launcher.
val pickMedia = registerForActivityResult(PickVisualMedia()) { uri ->
// Callback invoked after media selected or picker activity closed.
if (uri != null) {
Log.d("photo picker", "Selected URI: $uri")
} else {
Log.d("photo picker", "No media selected")
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun launchPhotoPickerWithTranscodingSupport() {
val mediaCapabilities = MediaCapabilities.Builder()
.addSupportedHdrType(MediaCapabilities.HdrType.TYPE_HLG10)
.build()
// Launch the photo picker and let the user choose only videos with
// transcoding enabled.
pickMedia.launch(PickVisualMediaRequest.Builder()
.setMediaType(PickVisualMedia.VideoOnly)
.setMediaCapabilitiesForTranscoding(mediaCapabilities)
.build())
}
A transcodificação feita pelo seletor de fotos é baseada nos recursos de mídia do app e no vídeo escolhido. Um URI para o vídeo transcodificado é retornado se a transcodificação for realizada.
Considerações importantes sobre a transcodificação HDR
- Desempenho e armazenamento:a transcodificação leva tempo de processamento e cria um novo arquivo, que consome espaço de armazenamento.
- Limite de duração do vídeo:para equilibrar a experiência do usuário e as restrições de armazenamento, há um limite de 1 minuto para a duração do vídeo.
- Gerenciamento de arquivos em cache:os arquivos transcodificados em cache são limpos periodicamente durante a manutenção ociosa para evitar o uso excessivo de armazenamento.
- Disponibilidade em dispositivos:a transcodificação do seletor de fotos é compatível com o Android 13 (nível 33 da API) e versões mais recentes.
- Integração de atividades do AndroidX:use a versão 1.11.0-alpha01
ou uma versão alfa/beta/RC/estável mais recente da biblioteca AndroidX Activity, já que
ela inclui a API
setMediaCapabilitiesForTranscoding
necessária.