L'archiviazione esterna sui dispositivi mobili è un supporto dati rimovibile a cui qualsiasi applicazione con le autorizzazioni appropriate può accedere. Secondo il Android Open Source Project, 2026, a partire da Android 10, Google ha introdotto Scoped Storage — un modello che limita l'accesso diretto al file system e richiede l'uso dell'API MediaStore per lavorare con file multimediali condivisi. Questo approccio migliora la sicurezza dei dati degli utenti e previene le fughe di informazioni tra le applicazioni.
Punti chiave
READ_EXTERNAL_STORAGE e WRITE_EXTERNAL_STORAGE sono obbligatorie per Android 9 e versioni precedentiArchiviazione esterna è un'area di memoria che non fa parte del sandbox protetto dell'applicazione ed è accessibile ad altri programmi. Su Android, questo termine si riferisce generalmente alla scheda SD, ma l'archiviazione esterna include anche unità USB collegate tramite adattatore OTG e unità cloud integrate a livello di file system. La differenza principale dall'archiviazione interna è la mancanza di isolamento: qualsiasi applicazione con le autorizzazioni appropriate può leggere e modificare i file nell'archiviazione esterna.
Su Android, l'archiviazione esterna ha due modalità principali: portatile e adottabile. Quando una scheda SD viene formattata come archiviazione portatile, rimane rimovibile e viene formattata in FAT32 o exFAT. In modalità di archiviazione adottabile, la scheda viene formattata in ext4 e crittografata con AES-128, dopo di che il sistema la tratta come un'estensione della memoria interna. La modalità adottabile è disponibile da Android 6.0 Marshmallow, ma i produttori di dispositivi spesso disabilitano questa funzione nel loro firmware. Secondo le statistiche di Google Play Console, solo circa il 12% dei dispositivi Android supporta l'archiviazione adottabile, pertanto non è consigliabile fare affidamento sull'espansione della memoria interna tramite scheda SD come unica opzione.
Su iOS, non ci sono schede SD tradizionali. Apple utilizza un'architettura chiusa in cui tutta l'archiviazione si basa su memoria flash interna e iCloud. Le unità esterne sono supportate tramite la porta Lightning o USB-C, ma l'accesso ad esse è limitato al file manager di sistema Files e alle applicazioni che si integrano con Document Picker. L'utente decide quali file aprire da una fonte esterna — l'applicazione non può scansionare un'unità connessa senza consenso esplicito.
La scelta del supporto esterno dipende dai requisiti di velocità, capacità e portabilità. Diversi tipi di supporti hanno caratteristiche di velocità, file system e casi d'uso diversi nelle applicazioni mobili.
| Tipo di supporto | Capacità max | Velocità di lettura | File system |
|---|---|---|---|
| SD UHS-I | 2 TB | fino a 104 MB/s | exFAT / FAT32 |
| SD UHS-II | 2 TB | fino a 312 MB/s | exFAT / FAT32 |
| USB 3.0 OTG | 2 TB | fino a 400 MB/s | exFAT / NTFS / FAT32 |
| USB-C SSD | 4 TB | fino a 1000 MB/s | exFAT / APFS / NTFS |
Le schede SD sono classificate per velocità di scrittura: Classe 10 (10 MB/s), U1 (10 MB/s), U3 (30 MB/s), V30 (30 MB/s) e V90 (90 MB/s). La registrazione video 4K richiede una scheda di almeno U3 o V30. Per le applicazioni mobili che lavorano con file multimediali di grandi dimensioni (elaborazione foto, montaggio video), si consiglia l'uso di schede di classe U3 e superiori. La velocità della scheda influisce direttamente sulle prestazioni dell'applicazione: registrare video 4K su una scheda Classe 10 può causare cadute di fotogrammi a causa della larghezza di banda insufficiente. Quando si sceglie una scheda SD per un'applicazione, prestare attenzione non solo alla classe di velocità, ma anche alla classificazione della Classe di Prestazione dell'Applicazione: A1 e A2 indicano le prestazioni minime di lettura e scrittura casuale, fondamentali per le operazioni di database e cache dell'applicazione.
USB-OTG (On-The-Go) consente di collegare unità USB esterne a un dispositivo mobile tramite un adattatore. Android supporta OTG dalla versione 3.1, ma il montaggio dell'unità richiede un kernel con supporto del file system. FAT32 e exFAT sono supportati nativamente, NTFS — solo su dispositivi con kernel personalizzato o tramite la libreria Paragon. Su iOS, il supporto per le unità USB è apparso in iOS 13 con l'app Files. Per lavorare con un'unità, l'applicazione deve utilizzare UIDocumentPickerViewController, che fornisce accesso solo ai file selezionati dall'utente — iOS non concede accesso completo al file system dell'unità.
I servizi cloud — iCloud, Google Drive, Dropbox — possono integrarsi nel file system del dispositivo tramite provider di sistema. Su iOS, iCloud Drive fa parte del contenitore Sandbox dell'applicazione e i file vengono sincronizzati automaticamente tra i dispositivi dell'utente. Su Android, Google Drive fornisce un'API per leggere e scrivere file, ma non avviene alcun montaggio diretto nel file system. Per le applicazioni mobili che lavorano con grandi volumi di dati, l'archiviazione cloud può fungere da alternativa alla scheda SD, specialmente su dispositivi senza slot di espansione.
Lavorare con l'archiviazione esterna su Android dipende dalla versione del sistema operativo e dal modello Scoped Storage. Il processo di accesso ai file differisce per Android 9 e versioni precedenti, Android 10–12 e Android 13+.
A partire da Android 10, il modo principale per accedere ai file multimediali condivisi è l'API MediaStore. Questa API fornisce un'interfaccia unificata per leggere e scrivere immagini, video e file audio nell'archiviazione condivisa. Un'applicazione non richiede l'autorizzazione READ_EXTERNAL_STORAGE per accedere ai propri file, ma la lettura di file di altre applicazioni richiede ancora l'autorizzazione esplicita dell'utente. MediaStore indicizza automaticamente i file multimediali e fornisce un ContentResolver per interrogarli.
val collection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
val projection = arrayOf(
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME
)
val cursor = contentResolver.query(collection, projection, null, null, null)
Dopo aver eseguito la query, si riceve un Cursor contenente gli URI dei file. Per leggere un file, aprire un InputStream tramite contentResolver.openInputStream(uri). La scrittura viene eseguita in modo simile tramite contentResolver.openOutputStream(uri). MediaStore gestisce automaticamente i conflitti di nomi e fornisce la possibilità di inserire nuovi file tramite contentResolver.insert(uri, values), che restituisce l'URI del file creato.
Storage Access Framework (SAF) è il metodo consigliato per accedere a file arbitrari su Android 10+. SAF fornisce una finestra di dialogo del selettore di file di sistema attraverso la quale l'utente concede all'applicazione l'accesso a un file o una directory specifici. L'applicazione riceve un URI di accesso che rimane valido fino al riavvio del dispositivo o fino a quando l'autorizzazione viene revocata esplicitamente nelle impostazioni. SAF non richiede le autorizzazioni READ_EXTERNAL_STORAGE o WRITE_EXTERNAL_STORAGE, semplificando la pubblicazione su Google Play e riducendo il numero di richieste di autorizzazione.
val requestCode = 42
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
startActivityForResult(intent, requestCode)
Su iOS, il lavoro con i file esterni è basato su UIDocumentPickerViewController, che l'utente apre per selezionare file o directory specifici. L'applicazione non ha accesso diretto al file system dell'unità esterna — solo ai file che l'utente ha esplicitamente selezionato. Dopo la selezione del file, l'applicazione riceve un URL temporaneo nel contenitore Sandbox e può lavorare con il file tramite FileManager.
UIDocumentPickerViewController consente all'utente di selezionare uno o più file da qualsiasi fonte disponibile: iCloud Drive, un'unità USB collegata o un servizio cloud di terze parti. Dopo la selezione, il controller restituisce un array di URL che l'applicazione può leggere durante la sessione. Per mantenere l'accesso dopo la chiusura dell'applicazione, è necessario chiamare startAccessingSecurityScopedResource() e salvare un segnalibro con ambito di sicurezza in UserDefaults.
let picker = UIDocumentPickerViewController(
forOpeningContentTypes: [.data, .image],
asCopy: true
)
picker.delegate = self
func documentPicker(
controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]
) {
guard let url = urls.first else { return }
let data = try Data(contentsOf: url)
}
Il parametro asCopy: true significa che iOS copierà il file nel contenitore Sandbox dell'applicazione e l'applicazione otterrà una propria copia indipendente dal file originale. Se viene specificato asCopy: false, l'applicazione riceve un riferimento al file originale, ma per accedervi è necessario chiamare url.startAccessingSecurityScopedResource(). Senza questa chiamata, la lettura del file genererà un'eccezione. Dopo aver terminato il lavoro con il file, chiamare sempre url.stopAccessingSecurityScopedResource() per rilasciare la risorsa e prevenire perdite di descrittori.
La sicurezza dell'archiviazione esterna è inferiore a quella dell'archiviazione interna perché i file sono accessibili ad altre applicazioni. Qualsiasi applicazione con autorizzazione READ_EXTERNAL_STORAGE può leggere tutti i file sulla scheda SD, inclusi quelli creati dall'applicazione per memorizzare temporaneamente dati sensibili. Un'applicazione dannosa potrebbe scansionare la scheda SD ed estrarre i dati dell'utente se non sono crittografati. Pertanto, si sconsiglia vivamente di memorizzare token di autenticazione, password o dati personali dell'utente nell'archiviazione esterna in testo semplice.
Su Android 10+, Scoped Storage limita significativamente la capacità delle applicazioni di accedere al file system condiviso. Un'applicazione può leggere senza autorizzazione solo i file che ha creato essa stessa, e l'accesso ai file di altre applicazioni richiede il consenso esplicito dell'utente tramite la finestra di dialogo SAF. Tuttavia, questa restrizione non si applica alle applicazioni con versione SDK target inferiore a 29 — continuano a funzionare secondo il vecchio modello, creando un rischio per gli utenti che non hanno aggiornato le loro applicazioni. Google Play richiede targetSdkVersion 29+ per tutte le applicazioni nuove e aggiornate dal 2021.
Formattazione e crittografia sono un altro importante aspetto di sicurezza. Una scheda SD formattata come archiviazione portatile non viene crittografata dal sistema per impostazione predefinita. Anche quando si utilizza l'archiviazione adottabile, la crittografia viene attivata solo se il produttore del dispositivo ha abilitato questa funzione nel firmware. Per proteggere i dati sensibili salvati nell'archiviazione esterna, utilizzare la libreria EncryptedFile di AndroidX Security, che crittografa ogni file singolarmente utilizzando AES256-GCM, indipendentemente dalla crittografia del sistema.
L'uso efficace dell'archiviazione esterna richiede un equilibrio tra disponibilità dei dati e sicurezza. Seguire queste regole per garantire un'archiviazione affidabile dei file utente.
Environment.getExternalStorageState() per controllare lo stato della scheda SD. La scheda potrebbe essere rimossa, danneggiata o non disponibile per la scritturaÈ importante ricordare che l'archiviazione esterna non garantisce l'integrità dei dati durante i guasti. Le schede SD hanno un numero limitato di cicli di riscrittura, specialmente i modelli economici di Classe 4 e Classe 6. Con scrittura intensiva (ad esempio, registrazione o caching di dati in streaming), una scheda potrebbe guastarsi entro pochi mesi. Per tali scenari, utilizzare la memoria interna o l'archiviazione cloud e salvare sull'archiviazione esterna solo i file la cui perdita l'utente considererebbe accettabile. Controllare regolarmente lo stato della scheda SD tramite StatFs e informare l'utente sugli errori critici del file system.
Domande frequenti
Su Android 13+, l'autorizzazione READ_EXTERNAL_STORAGE è stata sostituita da autorizzazioni più granulari: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO e READ_MEDIA_AUDIO. Per altri tipi di file, utilizzare SAF.
Sì, la funzione adoptable storage è disponibile su Android 6.0+. La scheda viene formattata in ext4 con crittografia AES-128. Tuttavia, molti produttori disabilitano questa opzione e circa l'88% dei dispositivi non supporta l'archiviazione adottabile.
Utilizzare il metodo Environment.getExternalStorageState() che restituisce una stringa di stato. Il valore MEDIA_MOUNTED significa che la scheda è disponibile per lettura e scrittura. Altri valori indicano errori o assenza di scheda.
Scoped Storage limita l'applicazione al proprio contenitore e alle gallerie multimediali condivise di MediaStore. L'accesso completo consente di leggere qualsiasi file sul dispositivo. Scoped Storage migliora la sicurezza dei dati dell'utente ed è obbligatorio per le nuove applicazioni.
Avviare un Intent con l'azione ACTION_OPEN_DOCUMENT_TREE, che aprirà una finestra di dialogo del selettore di directory di sistema. Dopo la selezione, si riceve un'autorizzazione URI valida fino al riavvio. Salvare questo URI in SharedPreferences per un uso successivo.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche