Keď sme spomenuli databázy, ukladanie dát na web alebo SharedPreferences
, dá sa pracovať aj s bežnými súbormi?
Odpoveď je, áno, dá... ale v praxi to mnohokrát vieme ošetriť inak (cez databázy, ukladanie dát na web, či SharedPreferences
.)
O súboroch je ťažké napísať niečo lepšie než uvádza tréningový manuál Saving Files na portále Androidu. Rozhodne je vhodné sa doň začítať.
Android poskytuje dva druhy úložísk: interné a externé. Delenie pochádza ešte z čias, keď bolo interné flash úložisko drahé a malé a predpokladalo sa, že do zariadenia si vložíte dodatočné externé úložisko v podobe SD karty.
Interné úložisko je vždy dostupné, pretože sa na ňom nachádza operačný systém, ale na starých zariadeniach môže byť pomerne malé (HTC Desire z roku 2010 dával všetkým aplikáciám len 150 MB miesta). Súbory, ktoré do tohto úložiska appka ukladá, sú prístupné len pre ňu (iné appky ju nevidia) a pri odinštalovaní aplikácie sú odstránené.
Externé úložisko je obvykle dostatočne veľké (rádovo v gigabajtoch), ale keďže sa na mnohých zariadeniach nachádza na SD karte, nemusí byť vždy dostupné. Súbory zapísané do externého úložiska sú verejné, môže ich teda čítať ľubovoľná appka alebo iné zariadenie. Ak sa appka odinštaluje, jej súbory sa odstránia len vtedy, ak boli vytvorené v adresári získanom cez volanie metódy getExternalFilesDir()
.
Context#getOpenFileOutput()
vráti pre názov súboru FileOutputStream
, do ktorého možno zapisovať. Ak súbor neexistuje, vytvorí sa v internom úložisku.Context#getOpenFileInput()
vráti pre názov súboru FileInputStream
, z ktorého možno čítať. Súbor sa musí nachádzať v internom úložisku. Context#getFilesDir()
vráti File
reprezentujúci adresár na internom úložisku, do ktorého môže appka ukladať svoje súbory. Context#getCacheDir()
vráti File
s adresárom pre dočasné súbory. Odporúča sa neprekročiť limit 1MB a súbory premazávať. Ak sa vyčerpá miesto na úložisku, Android môže (ale nemusí) súbory premazať bez varovania.Ak chceme zapisovať do externého úložiska, potrebujeme:
android.permission.WRITE_EXTERNAL_STORAGE
zistiť, či je externé úložisko namontované a dostupné na zápis
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
rozhodnúť sa, či chceme zapisovať súbory určené len pre našu appku alebo chceme zapisovať všeobecné, verejné súbory.
Environment.getExternalStoragePublicDirectory()
, kde v parametri uvedieme typ obsahu adresára. Príkladom je Environment.DIRECTORY_DOWNLOADS
pre stiahnuté súbory.Environment.getExternalFilesDir()
, kde uvedieme typ obsahu adresára alebo null
, ak chceme zapisovať priamo do koreňového adresára našej appky na externom úložisku.Pozor! Súbory a adresáre na externom úložisku sú verejné a ak poznáte adresárovú štruktúru, viete sa k nim jednoducho dostať!
Pre čítanie z úložiska potrebujeme:
android.permission.READ_EXTERNAL_STORAGE
zistiť, či je externé úložisko namontované a dostupné na čítanie
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
rozhodnete sa, či načítavate z verejného adresára alebo z adresára pre súbory patriace appke podobne ako v prípade zápisu.
Oprávnenie WRITE_EXTERNAL_STORAGE
v sebe zahŕňa i oprávnenie READ_EXTERNAL_STORAGE
.