O Android 14 lançou o recurso "Acesso a fotos selecionadas", que permite que os usuários concedam aos apps acesso a imagens e vídeos específicos na biblioteca, em vez de conceder acesso a todas as mídias de um determinado tipo.
Essa mudança só será ativada se o app for destinado ao Android 14 (nível 34 da API) ou mais recente. Se você ainda não usa o seletor de fotos, recomendamos implementá-lo no app para oferecer uma experiência consistente de seleção de imagens e vídeos que também melhore a privacidade do usuário sem precisar solicitar nenhuma permissão de armazenamento.
Se você mantiver seu próprio seletor de galeria usando permissões de armazenamento e precisar
manter o controle total sobre a implementação, adapte sua implementação
para usar a nova permissão READ_MEDIA_VISUAL_USER_SELECTED
. Se o app
não usar a nova permissão, o sistema vai executá-lo em um modo de
compatibilidade.
SDK de destino | READ_MEDIA_VISUAL_USER_SELECTED declarado |
Acesso às fotos selecionado ativado | Comportamento de UX |
---|---|---|---|
SDK 33 | Não | Não | N/A |
Sim | Sim | Controlado pelo app | |
SDK 34 | Não | Sim | Controlado pelo sistema (comportamento de compatibilidade) |
Sim | Sim | Controlado pelo app |
Criar ou adaptar seu próprio seletor de galeria
Criar seu próprio seletor de galeria exige muito desenvolvimento e manutenção, e o app precisa solicitar permissões de armazenamento para receber o consentimento explícito do usuário. Os usuários podem negar essas solicitações ou, se o app estiver sendo executado em um dispositivo com o Android 14 e for direcionado a essa versão (nível 34 da API) ou mais recente, limitar o acesso à mídia selecionada. A imagem a seguir mostra um exemplo de solicitação de permissões e seleção de mídia usando as novas opções.
Esta seção demonstra a abordagem recomendada para criar seu próprio seletor
de galeria usando MediaStore
. Se você já tem um seletor de galeria para seu app
e precisa ter controle total, use esses exemplos para adaptar sua
implementação. Se você não atualizar a implementação para processar o acesso
a fotos selecionadas, o sistema vai executar o app em um modo de compatibilidade.
Solicitar permissões
Primeiro, solicite as permissões de armazenamento corretas no manifesto do Android, dependendo da versão do SO:
<!-- Devices running Android 12L (API level 32) or lower -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- To handle the reselection within the app on devices running Android 14
or higher if your app targets Android 14 (API level 34) or higher. -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
Em seguida, solicite as permissões de execução corretas, que também dependem da versão do SO:
// Register ActivityResult handler
val requestPermissions = registerForActivityResult(RequestMultiplePermissions()) { results ->
// Handle permission requests results
// See the permission example in the Android platform samples: https://github.com/android/platform-samples
}
// Permission request logic
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO))
} else {
requestPermissions.launch(arrayOf(READ_EXTERNAL_STORAGE))
}
Alguns apps não precisam de permissões
A partir do Android 10 (nível 29 da API), os apps não precisam mais de permissões de armazenamento para adicionar
arquivos ao armazenamento compartilhado. Isso significa que os apps podem adicionar imagens à galeria, gravar vídeos e salvá-los no armazenamento compartilhado ou fazer o download de faturas em PDF sem precisar solicitar permissões de armazenamento. Caso o app adicione apenas arquivos ao armazenamento
compartilhado e não consulte imagens ou vídeos, pare de solicitar permissões de
armazenamento e defina um maxSdkVersion
da API de nível 28 no AndroidManifest.xml
:
<!-- No permission is needed to add files to shared storage on Android 10 (API level 29) or higher -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
Processar a nova seleção de mídia
Com o recurso Acesso às fotos selecionadas no Android 14, seu app precisa adotar a
nova permissão READ_MEDIA_VISUAL_USER_SELECTED
para controlar a nova seleção
de mídia e atualizar a interface para permitir que os usuários concedam ao app acesso
a um conjunto diferente de imagens e vídeos. A imagem a seguir mostra um exemplo de
como solicitar permissões e selecionar novamente a mídia:
Ao abrir a caixa de diálogo de seleção, fotos, vídeos ou ambos são exibidos, dependendo
das permissões solicitadas. Por exemplo, se você solicitar a
permissão READ_MEDIA_VIDEO
sem a READ_MEDIA_IMAGES
, apenas
vídeos vão aparecer na interface para que os usuários selecionem arquivos.
// Allow the user to select only videos
requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
É possível verificar se o app tem acesso total, parcial ou negado à biblioteca de fotos
do dispositivo e atualizar a interface de acordo. Solicite essas permissões
quando o app precisar de acesso ao armazenamento, em vez de na inicialização. A concessão de permissão pode ser alterada entre os callbacks do ciclo de vida do app
onStart
e onResume
, já que o usuário pode mudar o acesso nas configurações sem
fechar o app.
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
(
ContextCompat.checkSelfPermission(context, READ_MEDIA_IMAGES) == PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(context, READ_MEDIA_VIDEO) == PERMISSION_GRANTED
)
) {
// Full access on Android 13 (API level 33) or higher
} else if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
ContextCompat.checkSelfPermission(context, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED
) {
// Partial access on Android 14 (API level 34) or higher
} else if (ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
// Full access up to Android 12 (API level 32)
} else {
// Access denied
}
Consultar a biblioteca de dispositivos
Depois de verificar se você tem acesso às permissões de armazenamento corretas, interaja com MediaStore
para consultar a biblioteca do dispositivo. A mesma abordagem funciona
seja o acesso concedido parcial ou total:
data class Media(
val uri: Uri,
val name: String,
val size: Long,
val mimeType: String,
)
// Run the querying logic in a coroutine outside of the main thread to keep the app responsive.
// Keep in mind that this code snippet is querying only images of the shared storage.
suspend fun getImages(contentResolver: ContentResolver): List<Media> = withContext(Dispatchers.IO) {
val projection = arrayOf(
Images.Media._ID,
Images.Media.DISPLAY_NAME,
Images.Media.SIZE,
Images.Media.MIME_TYPE,
)
val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Query all the device storage volumes instead of the primary only
Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
} else {
Images.Media.EXTERNAL_CONTENT_URI
}
val images = mutableListOf<Media>()
contentResolver.query(
collectionUri,
projection,
null,
null,
"${Images.Media.DATE_ADDED} DESC"
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(Images.Media._ID)
val displayNameColumn = cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME)
val sizeColumn = cursor.getColumnIndexOrThrow(Images.Media.SIZE)
val mimeTypeColumn = cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE)
while (cursor.moveToNext()) {
val uri = ContentUris.withAppendedId(collectionUri, cursor.getLong(idColumn))
val name = cursor.getString(displayNameColumn)
val size = cursor.getLong(sizeColumn)
val mimeType = cursor.getString(mimeTypeColumn)
val image = Media(uri, name, size, mimeType)
images.add(image)
}
}
return@withContext images
}
Este snippet de código foi simplificado para ilustrar como interagir com MediaStore
.
Em um app pronto para produção, use a paginação com algo como a biblioteca
Paging para garantir um bom desempenho.
Consultar a última seleção
Os apps no Android 15 e mais recentes e no Android 14 com suporte a atualizações do sistema do Google Play podem
consultar a última seleção de imagens e vídeos feita pelo usuário no acesso parcial
ativando o QUERY_ARG_LATEST_SELECTION_ONLY
:
if (getExtensionVersion(Build.VERSION_CODES.U) >= 12) {
val queryArgs = bundleOf(
QUERY_ARG_SQL_SORT_ORDER to "${Images.Media.DATE_ADDED} DESC"
QUERY_ARG_LATEST_SELECTION_ONLY to true
)
contentResolver.query(collectionUri, projection, queryArgs, null)
}
O acesso a fotos e vídeos é preservado quando o dispositivo é atualizado
Nos casos em que o app está em um dispositivo que faz o upgrade de uma versão anterior para o Android 14, o sistema mantém acesso total às fotos e aos vídeos do usuário, além de conceder ao app algumas permissões automaticamente. O comportamento exato depende do conjunto de permissões concedidas ao app antes do upgrade do dispositivo para o Android 14.
Permissões do Android 13
Considere esta situação:
- O app é instalado em um dispositivo com o Android 13.
- O usuário concedeu as permissões
READ_MEDIA_IMAGES
eREAD_MEDIA_VIDEO
ao app. - O dispositivo é atualizado para o Android 14 enquanto o app ainda está instalado.
- O app começa a ser destinado ao Android 14 (nível 34 da API) ou versões mais recentes.
Nesse caso, o app ainda terá acesso total aos vídeos e fotos do usuário.
O sistema também mantém automaticamente as permissões READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
concedidas ao app.
Permissões do Android 12 e versões anteriores
Considere esta situação:
- O app é instalado em um dispositivo com o Android 13.
- O usuário concedeu a permissão
READ_EXTERNAL_STORAGE
ouWRITE_EXTERNAL_STORAGE
ao app. - O dispositivo é atualizado para o Android 14 enquanto o app ainda está instalado.
- O app começa a ser destinado ao Android 14 (nível 34 da API) ou versões mais recentes.
Nesse caso, o app ainda terá acesso total aos vídeos e fotos do usuário.
O sistema também concede automaticamente as
permissões READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
ao app.
Práticas recomendadas
Esta seção contém várias práticas recomendadas para usar a
permissão READ_MEDIA_VISUAL_USER_SELECTED
. Para mais informações, confira
nossas práticas recomendadas de permissões.
Não armazenar o estado da permissão permanentemente
Não armazene o estado de permissão de modo permanente, incluindo
SharedPreferences
ou DataStore
. O estado armazenado pode não estar sincronizado com
o estado real. O estado de permissão pode mudar após a redefinição da permissão,
a hibernação do app, uma mudança iniciada pelo usuário nas configurações do app ou quando
o app fica em segundo plano. Em vez disso, confira as permissões de armazenamento usando
ContextCompat.checkSelfPermission()
.
Não ter acesso total a fotos e vídeos
Com base nas mudanças apresentadas no Android 14, o app pode ter acesso parcial
à biblioteca de fotos do dispositivo. Se o app estiver armazenando dados MediaStore
em cache
quando eles são consultados com ContentResolver
, talvez o cache não esteja atualizado.
- Sempre consulte
MediaStore
usandoContentResolver
em vez de depender de um cache armazenado. - Mantenha os resultados na memória enquanto o app estiver em primeiro plano.
- Atualize os resultados quando o app passar pelo ciclo de vida
onResume
, porque o usuário pode alternar do acesso total para o parcial usando as configurações de permissão.
Tratar o acesso ao URI como temporário
Se o usuário escolher Selecionar fotos e vídeos na caixa de diálogo de permissões do
sistema, o acesso do app aos vídeos e fotos selecionados vai expirar.
Seu app precisa sempre processar o caso de não ter acesso a nenhuma Uri
, independente da autoridade.
Filtrar o tipo de mídia selecionável por permissão
A caixa de diálogo de seleção depende do tipo de permissão solicitada:
- Solicitar apenas
READ_MEDIA_IMAGES
mostra apenas imagens que podem ser selecionadas. - Solicitar apenas
READ_MEDIA_VIDEO
mostra apenas o vídeo como selecionável. - Solicitar
READ_MEDIA_IMAGES
eREAD_MEDIA_VIDEO
faz com que toda a biblioteca de fotos seja selecionável.
Com base nos casos de uso do app, solicite as permissões
corretas para evitar uma experiência ruim do usuário. Se um recurso espera apenas
que os vídeos sejam selecionados, solicite apenas READ_MEDIA_VIDEO
.
Solicitar permissões em uma única operação
Para evitar que os usuários recebam várias caixas de diálogo do ambiente de execução do sistema, solicite as
permissões READ_MEDIA_VISUAL_USER_SELECTED
, ACCESS_MEDIA_LOCATION
e "ler mídia"
(READ_MEDIA_IMAGES
, READ_MEDIA_VIDEO
ou ambas) em uma única operação.
Permitir que os usuários gerenciem a seleção
Quando o usuário escolher o modo de acesso parcial, o app não poderá presumir que a biblioteca de fotos do dispositivo está vazia e precisará permitir que o usuário conceda mais arquivos.
O usuário pode decidir alternar do acesso total para o parcial usando as configurações de permissão sem conceder acesso a alguns arquivos de mídia visual.
Modo de compatibilidade
Se você mantiver seu próprio seletor de galeria usando permissões de armazenamento, mas não
adaptar o app para usar a nova permissão READ_MEDIA_VISUAL_USER_SELECTED
,
o sistema vai executar o app em um modo de compatibilidade sempre que o usuário
precisar selecionar ou selecionar novamente a mídia.
Comportamento durante a seleção inicial de mídia
Durante a seleção inicial, se um usuário escolher "Selecionar fotos e vídeos" (consulte
Figura 1), as permissões READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
serão
concedidas durante a sessão do app, fornecendo uma permissão temporária e
acesso temporário aos vídeos e fotos selecionados pelo usuário. Quando seu app passa para o
segundo plano ou quando o usuário encerra o app, o sistema
nega essas permissões. Esse comportamento é igual ao de outras permissões únicas.
Comportamento durante a reclassificação de mídia
Se o app precisar acessar outras fotos e vídeos mais tarde, será necessário solicitar manualmente a permissão READ_MEDIA_IMAGES
ou
READ_MEDIA_VIDEO
mais uma vez. O sistema segue o mesmo fluxo da
solicitação de permissão inicial, pedindo que os usuários selecionem fotos e vídeos (consulte a
Figura 2).
Se o app estiver seguindo as práticas recomendadas de permissões, essa mudança não poderá
corromper o app. Isso é especialmente verdadeiro se o app não presumir que o acesso
ao URI é mantido, armazenar o estado de permissão do sistema ou atualizar o conjunto de
imagens exibidas após a mudança da permissão. No entanto, esse comportamento pode não
ser ideal, dependendo do caso de uso do app. Para oferecer a melhor experiência
aos usuários, recomendamos implementar o seletor de fotos ou adaptar o
seletor de galeria do app para processar esse comportamento diretamente usando a
permissão READ_MEDIA_VISUAL_USER_SELECTED
.