Android 14 introduce l'accesso alle foto selezionate, che consente agli utenti di concedere alle app l'accesso a immagini e video specifici nella raccolta, anziché a tutti i contenuti multimediali di un determinato tipo.
Questa modifica è attivata solo se la tua app ha come target Android 14 (livello API 34) o versioni successive. Se non utilizzi ancora il selettore di foto, ti consigliamo di implementarlo nella tua app per offrire un'esperienza coerente per la selezione di immagini e video che migliori anche la privacy dell'utente senza dover richiedere autorizzazioni per lo spazio di archiviazione.
Se gestisci il tuo selettore di gallerie utilizzando le autorizzazioni di archiviazione e devi mantenere il pieno controllo sull'implementazione, adatta l'implementazione per utilizzare la nuova autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
. Se la tua app
non utilizza la nuova autorizzazione, il sistema la esegue in una modalità di compatibilità.
SDK target | READ_MEDIA_VISUAL_USER_SELECTED dichiarato |
Accesso a Foto selezionato abilitato | Comportamento UX |
---|---|---|---|
SDK 33 | No | No | N/D |
Sì | Sì | Controllata dall'app | |
SDK 34 | No | Sì | Controllato dal sistema (comportamento compatibilità) |
Sì | Sì | Controllate dall'app |
Creare o adattare un selettore di gallerie
La creazione di un selettore di gallerie personalizzato richiede uno sviluppo e una manutenzione estensivi e la tua app deve richiedere le autorizzazioni di archiviazione per ottenere il consenso esplicito dell'utente. Gli utenti possono negare queste richieste o, se la tua app è in esecuzione su un dispositivo con Android 14 e ha come target Android 14 (livello API 34) o versioni successive, limitare l'accesso ai contenuti multimediali selezionati. L'immagine seguente mostra un esempio di richiesta di autorizzazioni e selezione di contenuti multimediali utilizzando le nuove opzioni.

Questa sezione illustra l'approccio consigliato per creare il tuo selettore
galleria utilizzando MediaStore
. Se gestisci già un selettore di gallerie per la tua app
e devi mantenere il pieno controllo, puoi utilizzare questi esempi per adattare la tua
implementazione. Se non aggiorni l'implementazione per gestire l'accesso alle foto selezionate, il sistema esegue la tua app in modalità di compatibilità.
Richiedi autorizzazioni
Innanzitutto, richiedi le autorizzazioni di archiviazione corrette nel file manifest di Android, a seconda della versione del sistema operativo:
<!-- 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" />
Quindi, richiedi le autorizzazioni di runtime corrette, anche in base alla versione del sistema operativo:
// 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))
}
Alcune app non richiedono autorizzazioni
A partire da Android 10 (livello API 29), le app non hanno più bisogno delle autorizzazioni di archiviazione per aggiungere file allo spazio di archiviazione condiviso. Ciò significa che le app possono aggiungere immagini alla galleria, registrare video e salvarli nello spazio di archiviazione condiviso o scaricare fatture PDF senza dover richiedere autorizzazioni di archiviazione. Se la tua app aggiunge solo file allo spazio di archiviazione condiviso e non esegue query su immagini o video, devi smettere di richiedere le autorizzazioni di archiviazione e impostare un maxSdkVersion
dell'API 28 nel tuo 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" />
Gestire la nuova selezione dei contenuti multimediali
Con la funzionalità di accesso a foto selezionate in Android 14, la tua app dovrebbe adottare la
nuova autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
per controllare la riselezione
dei contenuti multimediali e aggiornare l'interfaccia dell'app per consentire agli utenti di concedere all'app l'accesso
a un insieme diverso di immagini e video. L'immagine seguente mostra un esempio di richiesta di autorizzazioni e di selezione di nuovo dei contenuti multimediali:

Quando apri la finestra di dialogo di selezione, vengono mostrate foto, video o entrambi, a seconda delle autorizzazioni richieste. Ad esempio, se richiedi l'autorizzazione READ_MEDIA_VIDEO
senza l'autorizzazione READ_MEDIA_IMAGES
, nell'interfaccia utente verranno visualizzati solo i video per consentire agli utenti di selezionare i file.
// Allow the user to select only videos
requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
Puoi controllare se la tua app ha accesso completo, parziale o negato alla raccolta fotografica
del dispositivo e aggiornare l'interfaccia di conseguenza. Richiedi queste autorizzazioni
quando l'app ha bisogno di accedere allo spazio di archiviazione, anziché all'avvio. Tieni presente che la concessione dell'autorizzazione può essere modificata tra i callback del ciclo di vita dell'app onStart
e onResume
, in quanto l'utente può modificare l'accesso nelle impostazioni senza chiudere l'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
}
Esegui query sulla raccolta di dispositivi
Dopo aver verificato di disporre dell'accesso alle autorizzazioni di archiviazione corrette, puoi interagire con MediaStore
per eseguire query sulla raccolta di dispositivi (lo stesso approccio funziona se l'accesso concesso è parziale o completo):
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
}
Questo snippet di codice è semplificato per illustrare come interagire con MediaStore
.
In un'app pronta per la produzione, utilizza la paginazione con, ad esempio, la libreria di paginazione per garantire buone prestazioni.
Esegui una query sull'ultima selezione
Le app su Android 15 e versioni successive e su Android 14 con il supporto degli aggiornamenti di sistema di Google Play possono eseguire query sull'ultima selezione di immagini e video effettuata dall'utente con accesso parziale attivando 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)
}
L'accesso a foto e video viene mantenuto durante l'upgrade del dispositivo
Se la tua app è su un dispositivo che esegue l'upgrade da una versione precedente di Android ad Android 14, il sistema mantiene l'accesso completo alle foto e ai video dell'utente e concede automaticamente alcune autorizzazioni alla tua app. Il comportamento esatto dipende dall'insieme di autorizzazioni concesse alla tua app prima dell'upgrade del dispositivo ad Android 14.
Autorizzazioni di Android 13
Considera la seguente situazione:
- La tua app è installata su un dispositivo con Android 13.
- L'utente ha concesso alla tua app l'autorizzazione
READ_MEDIA_IMAGES
e l'autorizzazioneREAD_MEDIA_VIDEO
. - Il dispositivo esegue quindi l'upgrade ad Android 14 mentre l'app è ancora installata.
- La tua app inizia a avere come target Android 14 (livello API 34) o versioni successive.
In questo caso, la tua app ha ancora accesso completo alle foto e ai video dell'utente.
Il sistema mantiene inoltre automaticamente le autorizzazioni READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
concesse alla tua app.
Autorizzazioni da Android 12 e versioni precedenti
Considera la seguente situazione:
- La tua app è installata su un dispositivo con Android 13.
- L'utente ha concesso alla tua app l'autorizzazione
READ_EXTERNAL_STORAGE
oWRITE_EXTERNAL_STORAGE
. - Il dispositivo esegue quindi l'upgrade ad Android 14 mentre l'app è ancora installata.
- La tua app inizia a avere come target Android 14 (livello API 34) o versioni successive.
In questo caso, la tua app ha ancora accesso completo alle foto e ai video dell'utente.
Il sistema concede automaticamente alla tua app anche l'autorizzazione READ_MEDIA_IMAGES
e l'autorizzazione READ_MEDIA_VIDEO
.
Best practice
Questa sezione contiene diverse best practice per l'utilizzo dell'autorizzazioneREAD_MEDIA_VISUAL_USER_SELECTED
. Per ulteriori informazioni, consulta le nostre best practice sulle autorizzazioni.
Non memorizzare lo stato dell'autorizzazione in modo permanente
Non memorizzare lo stato dell'autorizzazione in modo permanente, ad esempio SharedPreferences
o DataStore
. Lo stato memorizzato potrebbe non essere sincronizzato con lo stato effettivo. Lo stato dell'autorizzazione può cambiare dopo la reimpostazione delle autorizzazioni, la ibernazione dell'app, una modifica delle impostazioni dell'app avviata dall'utente o quando l'app passa in background. Controlla invece le autorizzazioni di archiviazione utilizzando
ContextCompat.checkSelfPermission()
.
Non dare per scontato l'accesso completo a foto e video
In base alle modifiche introdotte in Android 14, la tua app potrebbe avere accesso solo parziale alla raccolta di foto del dispositivo. Se l'app memorizza nella cache i dati di MediaStore
quando viene eseguita una query utilizzando ContentResolver
, la cache potrebbe non essere aggiornata.
- Esegui sempre query su
MediaStore
utilizzandoContentResolver
, anziché fare affidamento su una cache memorizzata. - Mantieni i risultati in memoria mentre l'app è in primo piano.
- Aggiorna i risultati quando la tua app attraversa il ciclo di vita dell'app
onResume
, in quanto l'utente potrebbe passare dall'accesso completo all'accesso parziale tramite le impostazioni dell'autorizzazione.
Considera l'accesso URI come temporaneo
Se l'utente sceglie Seleziona foto e video nella finestra di dialogo delle autorizzazioni di sistema, l'accesso della tua app alle foto e ai video selezionati scade.
La tua app deve sempre gestire il caso in cui non ha accesso a nessun Uri
, indipendentemente dalla sua autorità.
Filtrare il tipo di contenuti multimediali selezionabili in base all'autorizzazione
La finestra di dialogo di selezione è sensibile al tipo di autorizzazione richiesta:
- Se richiedi solo
READ_MEDIA_IMAGES
, vengono mostrate solo le immagini selezionabili. - Se richiedi solo
READ_MEDIA_VIDEO
, il video sarà l'unico elemento selezionabile. - Se richiedi sia
READ_MEDIA_IMAGES
siaREAD_MEDIA_VIDEO
, l'intera raccolta fotografica è selezionabile.
In base ai casi d'uso della tua app, devi assicurarti di richiedere le
autorizzazioni appropriate per evitare un'esperienza utente negativa. Se una funzionalità prevede solo la selezione di video, assicurati di richiedere solo READ_MEDIA_VIDEO
.
Richiedere le autorizzazioni in un'unica operazione
Per impedire agli utenti di visualizzare più finestre di dialogo di runtime del sistema, richiedi le autorizzazioni READ_MEDIA_VISUAL_USER_SELECTED
, ACCESS_MEDIA_LOCATION
e "Lettura di contenuti multimediali" (READ_MEDIA_IMAGES
, READ_MEDIA_VIDEO
o entrambe) in un'unica operazione.
Consenti agli utenti di gestire la propria selezione
Quando l'utente sceglie la modalità di accesso parziale, la tua app non deve presumere che la raccolta di foto del dispositivo sia vuota e deve consentire all'utente di concedere l'accesso a più file.
L'utente può decidere di passare dall'accesso completo all'accesso parziale tramite le impostazioni di autorizzazione senza concedere l'accesso ad alcuni file multimediali visivi.
Modalità di compatibilità
Se gestisci il tuo selettore della galleria utilizzando le autorizzazioni di archiviazione, ma non hai
adattato la tua app per utilizzare la nuova autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
, il sistema esegue la tua app in una modalità di compatibilità ogni volta che l'utente deve selezionare o selezionare nuovamente i contenuti multimediali.
Comportamento durante la selezione iniziale dei contenuti multimediali
Durante la selezione iniziale, se un utente sceglie "Seleziona foto e video" (vedi
Figura 1), le autorizzazioni READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
vengono
concedute durante la sessione dell'app, fornendo una concessione temporanea delle autorizzazioni e
accesso temporaneo alle foto e ai video selezionati dall'utente. Quando l'app viene spostata in background o quando l'utente la chiude attivamente, il sistema alla fine nega queste autorizzazioni. Questo comportamento è uguale a quello delle altre autorizzazioni una tantum.
Comportamento durante la nuova selezione dei contenuti multimediali
Se in un secondo momento la tua app ha bisogno di accedere ad altre foto e altri video, devi richiedere nuovamente l'autorizzazione READ_MEDIA_IMAGES
o READ_MEDIA_VIDEO
. Il sistema segue lo stesso flusso della richiesta di autorizzazione iniziale, chiedendo agli utenti di selezionare foto e video (vedi figura 2).
Se la tua app segue le best practice per le autorizzazioni, questa modifica non dovrebbe interrompere il suo funzionamento. Ciò vale soprattutto se l'app non presuppone che l'accesso URI venga mantenuto, memorizza lo stato dell'autorizzazione di sistema o aggiorna l'insieme di immagini visualizzate dopo le modifiche alle autorizzazioni. Tuttavia, questo comportamento potrebbe non essere ideale a seconda del caso d'uso della tua app. Per offrire la migliore esperienza ai tuoi utenti, ti consigliamo di implementare il selettore di foto o di adattare il selettore della galleria della tua app per gestire questo comportamento direttamente utilizzando l'autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
.