Android 14 introduce l'Accesso alle foto selezionate, che consente agli utenti di concedere alle app l'accesso a immagini e video specifici nella loro raccolta, anziché concedere l'accesso a tutti i contenuti multimediali di un determinato tipo.
Questa modifica viene 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 di archiviazione.
Se gestisci il tuo selettore galleria utilizzando le autorizzazioni di archiviazione e devi mantenere il controllo completo sull'implementazione, adatta l'implementazione per utilizzare la nuova autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
. Se l'app non utilizza la nuova autorizzazione, il sistema esegue l'app in una modalità di compatibilità.
SDK target | READ_MEDIA_VISUAL_USER_SELECTED dichiarato |
Accesso alle foto selezionate attivato | Comportamento UX |
---|---|---|---|
SDK 33 | No | No | N/A |
Sì | Sì | Controllata dall'app | |
SDK 34 | No | Sì | Controllata dal sistema (comportamento compatibile) |
Sì | Sì | Controllata dall'app |
Creare o adattare il proprio selettore galleria
La creazione di un selettore galleria personalizzato richiede operazioni di sviluppo e manutenzione complete e la tua app deve richiedere autorizzazioni per lo spazio di archiviazione per ottenere il consenso esplicito dell'utente. Gli utenti possono rifiutare queste richieste o, se la tua app è in esecuzione su un dispositivo con Android 14 e la tua app 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 dei contenuti multimediali utilizzando le nuove opzioni.
Questa sezione mostra l'approccio consigliato per la creazione di un selettore galleria utilizzando MediaStore
. Se gestisci già un selettore galleria per la tua app
e devi mantenere il controllo completo, puoi utilizzare questi esempi per adattare
l'implementazione. Se non aggiorni l'implementazione per gestire l'accesso
Foto selezionate, il sistema esegue l'app in modalità di compatibilità.
Richiedi autorizzazioni
Innanzitutto, richiedi le autorizzazioni corrette per lo spazio di archiviazione nel file manifest 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 a seconda della 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 hanno bisogno delle autorizzazioni
A partire da Android 10 (livello API 29), le app non hanno più bisogno delle autorizzazioni di accesso allo spazio 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 le autorizzazioni di archiviazione. Se la tua app aggiunge file solo allo spazio di archiviazione condiviso e non esegue query su immagini o video, devi interrompere la richiesta delle autorizzazioni di archiviazione e impostare un maxSdkVersion
dell'API 28 in 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 selezione dei contenuti multimediali
Con la funzionalità Accesso alle foto selezionate in Android 14, la tua app dovrebbe adottare la
nuova autorizzazione di READ_MEDIA_VISUAL_USER_SELECTED
per controllare la rielezione 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 riselezione dei contenuti multimediali:
Quando apri la finestra di dialogo di selezione, vengono visualizzati foto, video o entrambi, a seconda delle autorizzazioni richieste. Ad esempio, se richiedi l'autorizzazione
READ_MEDIA_VIDEO
senza questa autorizzazione READ_MEDIA_IMAGES
, nell'interfaccia utente verranno visualizzati solo
i video e gli utenti potranno 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
}
Eseguire query sulla libreria di dispositivi
Dopo aver verificato di avere accesso alle autorizzazioni corrette per lo spazio di archiviazione, puoi interagire con MediaStore
per eseguire query sulla libreria dei dispositivi (lo stesso approccio funziona indipendentemente dal fatto che l'accesso concesso sia parziale o totale):
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 mostrare come interagire con MediaStore
.
In un'app pronta per la produzione, utilizza l'impaginazione con qualcosa come la libreria di pagine cercate per garantire buone prestazioni.
L'accesso a foto e video viene mantenuto quando il dispositivo viene eseguito l'upgrade
Nel caso in cui la tua app si trovi 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 all'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 l'autorizzazione
READ_MEDIA_IMAGES
eREAD_MEDIA_VIDEO
alla tua app. - Il dispositivo esegue l'upgrade ad Android 14 mentre l'app è ancora installata.
- La tua app inizia ad avere come target Android 14 (livello API 34) o versioni successive.
In questo caso, la tua app ha comunque accesso completo alle foto e ai video dell'utente.
Il sistema inoltre mantiene automaticamente le autorizzazioni READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
concesse alla tua app.
Autorizzazioni di Android 12 e versioni precedenti
Considera la seguente situazione:
- La tua app è installata su un dispositivo con Android 13.
- L'utente ha concesso l'autorizzazione
READ_EXTERNAL_STORAGE
oWRITE_EXTERNAL_STORAGE
alla tua app. - Il dispositivo esegue l'upgrade ad Android 14 mentre l'app è ancora installata.
- La tua app inizia ad avere come target Android 14 (livello API 34) o versioni successive.
In questo caso, la tua app ha comunque accesso completo alle foto e ai video dell'utente.
Il sistema concede automaticamente anche l'autorizzazione READ_MEDIA_IMAGES
e
READ_MEDIA_VIDEO
alla tua app.
Best practice
Questa sezione contiene diverse best practice per l'utilizzo dell'autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
. Per ulteriori informazioni, consulta le nostre best practice per le autorizzazioni.
Non archiviare lo stato di autorizzazione in modo permanente
Non archiviare lo stato di autorizzazione in modo permanente, incluse
SharedPreferences
o DataStore
. Lo stato archiviato potrebbe non essere
sincronizzato con quello effettivo. Lo stato dell'autorizzazione può cambiare dopo la reimpostazione dell'autorizzazione, l'ibernazione dell'app, una modifica avviata dall'utente nelle impostazioni dell'app o quando l'app passa in background. Verifica invece le autorizzazioni per lo spazio di archiviazione utilizzando ContextCompat.checkSelfPermission()
.
Non presupporre l'accesso completo a foto e video
In base alle modifiche introdotte in Android 14, la tua app potrebbe avere accesso solo
parzialmente alla raccolta fotografica del dispositivo. Se l'app memorizza nella cache i dati MediaStore
quando viene eseguita una query utilizzando ContentResolver
, la cache potrebbe non essere aggiornata.
- Esegui sempre query su
MediaStore
utilizzandoContentResolver
, anziché affidarti a una cache archiviata. - Mantieni i risultati in memoria mentre l'app è in primo piano.
- Aggiorna i risultati quando l'app completa il ciclo di vita dell'app
onResume
, in quanto l'utente potrebbe passare dall'accesso completo all'accesso parziale tramite le impostazioni delle autorizzazioni.
Tratta l'accesso URI come temporaneo
Se l'utente sceglie Seleziona foto e video nella finestra di dialogo delle autorizzazioni di sistema, l'accesso dell'app alle foto e ai video selezionati scadrà prima o poi.
La tua app dovrebbe sempre gestire il caso in cui non abbia accesso a Uri
, indipendentemente dalla sua autorità.
Filtra il tipo di media selezionabile in base all'autorizzazione
La finestra di dialogo di selezione è sensibile al tipo di autorizzazione richiesto:
- Se richiedi solo
READ_MEDIA_IMAGES
, vengono mostrate solo le immagini selezionabili. - Se richiedi solo
READ_MEDIA_VIDEO
, viene mostrato solo il video selezionabile. - Se richiedi sia
READ_MEDIA_IMAGES
cheREAD_MEDIA_VIDEO
, viene mostrata l'intera raccolta fotografica.
In base ai casi d'uso della tua app, assicurati di richiedere le autorizzazioni corrette per evitare un'esperienza utente scadente. Se una funzionalità prevede che vengano selezionati
solo i video, assicurati di richiedere solo READ_MEDIA_VIDEO
.
Richiedi autorizzazioni in una singola 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) con 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 fotografica del dispositivo sia vuota e dovrebbe consentire all'utente di concedere più file.
L'utente può decidere di passare dall'accesso completo all'accesso parziale tramite le impostazioni delle autorizzazioni senza concedere l'accesso ad alcuni file multimediali visivi.
Modalità compatibilità
Se gestisci il tuo selettore galleria utilizzando le autorizzazioni di archiviazione, ma non hai
adattato la tua app a 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 riselezionare 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), vengono concesse le autorizzazioni READ_MEDIA_IMAGES
e READ_MEDIA_VIDEO
durante la sessione dell'app, fornendo una concessione di autorizzazione temporanea e l'accesso temporaneo alle foto e ai video selezionati dall'utente. Quando l'app passa in background o quando l'utente termina attivamente l'app, il sistema alla fine nega le autorizzazioni. Questo comportamento è analogo alle altre autorizzazioni una tantum.
Comportamento durante la rielezione dei media
Se la tua app ha bisogno di accedere a foto e video aggiuntivi in un secondo momento, dovrai
richiedere di nuovo l'autorizzazione READ_MEDIA_IMAGES
o
READ_MEDIA_VIDEO
manualmente. 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 relative alle autorizzazioni, questa modifica non dovrebbe interrompere l'app. Questo vale in particolare se la tua app non presuppone che venga mantenuto l'accesso all'URI, memorizzi lo stato delle autorizzazioni di sistema o aggiorna il set di immagini visualizzate dopo la modifica dell'autorizzazione. Tuttavia, questo comportamento potrebbe non essere
ideale a seconda del caso d'uso della tua app. Per offrire ai tuoi utenti un'esperienza ottimale, ti consigliamo di implementare il selettore di foto o di adattare il selettore galleria della tua app per gestire questo comportamento direttamente utilizzando l'autorizzazione READ_MEDIA_VISUAL_USER_SELECTED
.