Spoljašnje skladište na mobilnim uređajima je izmenjivi medijum podataka kojem svaka aplikacija sa odgovarajućim dozvolama može pristupiti. Prema Android Open Source Project, 2026, počevši od Androida 10, Google je uveo Scoped Storage — model koji ograničava direktan pristup sistemu datoteka i zahteva korišćenje MediaStore API za rad sa deljenim medijskim datotekama. Ovaj pristup povećava bezbednost korisničkih podataka i sprečava curenje informacija između aplikacija.
Glavno
READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE su obavezne za Android 9 i nižeSpoljašnje skladište — je oblast memorije koja nije u zaštićenom sendboks kontejneru aplikacije i dostupna je drugim programima. Na Androidu, ovaj izraz se obično odnosi na SD karticu, ali spoljašnje skladište takođe uključuje USB diskove povezane preko OTG adaptera i cloud diskove integrisane na nivou sistema datoteka.
Na Androidu je spoljašnje skladište predstavljeno sa dva glavna načina: prenosivi (portable) i unutrašnji (adoptable). Prilikom formatiranja SD kartice kao prenosivog skladišta, ona ostaje izmenjiva i formatira se u FAT32 ili exFAT. U režimu adoptable storage, kartica se formatira u ext4 i šifruje AES-128, nakon čega je sistem doživljava kao proširenje interne memorije. Režim adoptable je dostupan počevši od Android 6.0 Marshmallow, ali proizvođači uređaja često isključuju ovu mogućnost u svojim firmware-ima. Prema statistici Google Play Console, samo oko 12% Android uređaja podržava adoptable storage, stoga se ne preporučuje oslanjanje na proširenje interne memorije putem SD kartice kao jedine opcije.
Na iOS nema tradicionalnih SD kartica. Apple koristi zatvorenu arhitekturu gde je celokupno skladištenje izgrađeno na internoj fleš memoriji i iCloud-u. Spoljašnji uređaji se podržavaju preko Lightning ili USB-C porta, ali je pristup njima ograničen na sistemski menadžer datoteka Files i aplikacije koje se integrišu sa Document Picker-om. Korisnik sam odlučuje koje datoteke će otvoriti iz spoljašnjeg izvora — aplikacija ne može skenirati povezani uređaj bez eksplicitnog pristanka.
Izbor spoljašnjeg medijuma zavisi od zahteva za brzinom, kapacitetom i prenosivošću. Različiti tipovi medijuma imaju različite karakteristike brzine, sisteme datoteka i scenarije korišćenja u mobilnim aplikacijama.
| Tip medijuma | Maks. kapacitet | Brzina čitanja | Sistem datoteka |
|---|---|---|---|
| SD UHS-I | 2 TB | do 104 MB/s | exFAT / FAT32 |
| SD UHS-II | 2 TB | do 312 MB/s | exFAT / FAT32 |
| USB 3.0 OTG | 2 TB | do 400 MB/s | exFAT / NTFS / FAT32 |
| USB-C SSD | 4 TB | do 1000 MB/s | exFAT / APFS / NTFS |
SD kartice se klasifikuju prema brzini pisanja: Class 10 (10 MB/s), U1 (10 MB/s), U3 (30 MB/s), V30 (30 MB/s) i V90 (90 MB/s). Za snimanje 4K videa potrebna je kartica najmanje U3 ili V30. Za mobilne aplikacije koje rade sa velikim medijskim datotekama (obrada fotografija, video montaža), preporučuje se korišćenje kartica klase U3 i više. Brzina kartice direktno utiče na performanse aplikacije: snimanje 4K videa na karticu Class 10 može izazvati gubitak frejmova zbog nedovoljnog protoka. Prilikom odabira SD kartice za aplikaciju, obratite pažnju ne samo na klasu brzine, već i na rejting Application Performance Class: A1 i A2 ukazuju na minimalne performanse nasumičnog čitanja i pisanja, kritične za rad baza podataka i keša aplikacija.
USB-OTG (On-The-Go) omogućava povezivanje spoljašnjih USB uređaja sa mobilnim uređajem putem adaptera. Android podržava OTG počevši od verzije 3.1, ali za montiranje uređaja potrebno je jezgro sa podrškom za sistem datoteka. FAT32 i exFAT se podržavaju iz kutije, NTFS — samo na uređajima sa prilagođenim jezgrom ili putem Paragon biblioteke. Na iOS-u, podrška za USB uređaje pojavila se u iOS 13 zajedno sa aplikacijom Files. Za rad sa uređajem, aplikacija mora koristiti UIDocumentPickerViewController, koji otvara pristup samo datotekama koje je korisnik izabrao — iOS ne pruža potpuni pristup sistemu datoteka uređaja.
Cloud servisi — iCloud, Google Drive, Dropbox — mogu se integrisati u sistem datoteka uređaja preko sistemskih provajdera. Na iOS-u, iCloud Drive je deo Sandbox kontejnera aplikacije, a datoteke se automatski sinhronizuju između korisničkih uređaja. Na Androidu, Google Drive pruža API za čitanje i pisanje datoteka, ali ne dolazi do direktnog montiranja u sistem datoteka. Za mobilne aplikacije koje rade sa velikim količinama podataka, cloud skladište može poslužiti kao alternativa SD kartici, posebno na uređajima bez slot za proširenje.
Rad sa spoljašnjim skladištem na Androidu zavisi od verzije operativnog sistema i modela Scoped Storage. Proces pristupa datotekama se razlikuje za Android 9 i niže, Android 10–12 i Android 13+.
Počevši od Android 10, glavni način pristupa deljenim medijskim datotekama je MediaStore API. Ovaj API pruža objedinjeni interfejs za čitanje i pisanje slika, video zapisa i audio datoteka u deljenom skladištu. Aplikaciji nije potrebna dozvola READ_EXTERNAL_STORAGE za pristup sopstvenim datotekama, ali za čitanje datoteka drugih aplikacija i dalje je potrebna eksplicitna dozvola korisnika. MediaStore automatski indeksira medijske datoteke i pruža ContentResolver za njihovo pretraživanje.
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)
Nakon izvršenja upita, dobijate Cursor koji sadrži URI datoteka. Za čitanje datoteke otvorite InputStream putem contentResolver.openInputStream(uri). Pisanje se vrši analogno putem contentResolver.openOutputStream(uri). MediaStore automatski obrađuje konflikte imena i pruža mogućnost ubacivanja novih datoteka putem contentResolver.insert(uri, values), koji vraća URI kreirane datoteke.
Storage Access Framework (SAF) — preporučeni način za pristup proizvoljnim datotekama na Android 10+. SAF pruža sistemski dijalog za izbor datoteka, putem kojeg korisnik daje aplikaciji pristup određenoj datoteci ili direktorijumu. Aplikacija dobija URI pristupa koji važi do ponovnog pokretanja uređaja ili do eksplicitnog povlačenja dozvole putem podešavanja. SAF ne zahteva dozvole READ_EXTERNAL_STORAGE ili WRITE_EXTERNAL_STORAGE, što pojednostavljuje objavljivanje na Google Play-u i smanjuje broj zahteva za dozvole.
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)
Na iOS-u, rad sa spoljašnjim datotekama se obavlja putem UIDocumentPickerViewController-a, koji korisnik otvara za izbor određenih datoteka ili direktorijuma. Aplikacija nema direktan pristup sistemu datoteka spoljašnjeg uređaja — samo datotekama koje je korisnik eksplicitno izabrao. Nakon izbora datoteke, aplikacija dobija privremenu URL adresu u Sandbox kontejneru i može raditi sa datotekom putem FileManager-a.
UIDocumentPickerViewController omogućava korisniku da izabere jednu ili više datoteka iz bilo kog dostupnog izvora: iCloud Drive, povezanog USB uređaja, trećeg cloud servisa. Nakon izbora, kontroler vraća niz URL adresa koje aplikacija može čitati tokom sesije. Za očuvanje pristupa nakon zatvaranja aplikacije, potrebno je pozvati startAccessingSecurityScopedResource() i sačuvati bezbednosni bookmark u 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)
}
Parametar asCopy: true znači da će iOS kopirati datoteku u Sandbox kontejner aplikacije, a aplikacija će dobiti sopstvenu kopiju nezavisnu od originalne datoteke. Ako se navede asCopy: false, aplikacija dobija referencu na originalnu datoteku, ali za pristup njoj potrebno je pozvati url.startAccessingSecurityScopedResource(). Bez ovog poziva, čitanje datoteke će izazvati izuzetak. Nakon završetka rada sa datotekom, obavezno pozovite url.stopAccessingSecurityScopedResource(), da zatvorite resurs i sprečite curenje deskriptora.
Bezbednost spoljašnjeg skladišta je niža od Internal Storage-a jer su datoteke dostupne drugim aplikacijama. Bilo koja aplikacija sa dozvolom READ_EXTERNAL_STORAGE može pročitati sve datoteke na SD kartici, uključujući one koje je vaša aplikacija kreirala za privremeno skladištenje poverljivih podataka. Zlonamerna aplikacija može skenirati SD karticu i izvući korisničke podatke ako nisu šifrovani. Stoga se kategorički ne preporučuje čuvanje tokena za autentifikaciju, lozinki ili ličnih podataka korisnika u spoljašnjem skladištu u otvorenom obliku.
Na Android 10+ Scoped Storage značajno ograničava mogućnosti aplikacija za pristup deljenom sistemu datoteka. Aplikacija može bez dozvole čitati samo datoteke koje je sama kreirala, a za pristup datotekama drugih aplikacija potrebna je eksplicitna saglasnost korisnika putem SAF dijaloga. Međutim, ovo ograničenje se ne odnosi na aplikacije sa ciljnom verzijom SDK ispod 29 — one nastavljaju da rade po starom modelu, što stvara rizik za korisnike koji nisu ažurirali svoje aplikacije. Google Play od 2021. godine zahteva targetSdkVersion 29+ za sve nove i ažurirane aplikacije.
Formatiranje i šifrovanje — još jedan važan aspekt bezbednosti. SD kartica formatirana kao prenosivo skladište nije šifrovana od strane sistema podrazumevano. Čak i pri korišćenju adoptable storage, šifrovanje se aktivira samo ako je proizvođač uređaja uključio ovu mogućnost u firmware. Za zaštitu poverljivih podataka koji se čuvaju u spoljašnjem skladištu, koristite biblioteku EncryptedFile iz AndroidX Security, koja šifruje svaku datoteku posebno pomoću AES256-GCM, nezavisno od sistemskog šifrovanja.
Efikasno korišćenje spoljašnjeg skladišta zahteva balans između dostupnosti podataka i bezbednosti. Pridržavajte se sledećih pravila za obezbeđivanje pouzdanog skladištenja korisničkih datoteka.
Environment.getExternalStorageState() za proveru stanja SD kartice. Kartica može biti izvađena, oštećena ili nedostupna za pisanjeVažno je zapamtiti da spoljašnje skladište ne garantuje očuvanje podataka pri kvarovima. SD kartice imaju ograničen resurs ciklusa prepisivanja, posebno budžetni modeli klase Class 4 i Class 6. Pri intenzivnom pisanju (na primer, logovanje ili keširanje podataka u toku), kartica može otkazati u roku od nekoliko meseci. Za takve scenarije koristite internu memoriju ili cloud skladište, a na spoljašnjem skladištu čuvajte samo datoteke čiji gubitak korisnik smatra prihvatljivim. StatFs i obaveštavajte korisnika o kritičnim greškama sistema datoteka.
Često postavljana pitanja
Na Android 13+ dozvola READ_EXTERNAL_STORAGE je zamenjena preciznijim: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO i READ_MEDIA_AUDIO. Za pristup drugim tipovima datoteka koristite SAF.
Da, funkcija adoptable storage je dostupna na Android 6.0+. Kartica se formatira u ext4 sa AES-128 šifrovanjem. Međutim, mnogi proizvođači isključuju ovu opciju, a oko 88% uređaja ne podržava adoptable storage.
Koristite metod Environment.getExternalStorageState(), koji vraća niz stanja. Vrednost MEDIA_MOUNTED znači da je kartica dostupna za čitanje i pisanje. Ostale vrednosti ukazuju na greške ili odsustvo kartice.
Scoped Storage ograničava aplikaciju na njen sopstveni kontejner i deljenu MediaStore medijateku. Potpuni pristup dozvoljava čitanje bilo kojih datoteka na uređaju. korisničkih podataka i obavezan je za nove aplikacije.
Pokrenite Intent sa radnjom ACTION_OPEN_DOCUMENT_TREE, koji će otvoriti sistemski dijalog za izbor direktorijuma. Nakon izbora, dobićete URI dozvolu koja važi do ponovnog pokretanja. Sačuvajte ovaj URI u SharedPreferences za kasniju upotrebu.
Zaključak
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође