Bežné súbory v Androide

Bežné súbory v Androide

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ť.

Dva druhy úložísk

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().

Prehľad API pre súbory v internom úložisku

  • 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.

Prehľad API pre súbory v externom úložisku

Zápis na externé úložisko

Ak chceme zapisovať do externého úložiska, potrebujeme:

  1. získať oprávnenie android.permission.WRITE_EXTERNAL_STORAGE
  2. 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;
    }
    
  3. rozhodnúť sa, či chceme zapisovať súbory určené len pre našu appku alebo chceme zapisovať všeobecné, verejné súbory.

    1. verejný súbor zapíšeme do adresára, ktorý získame cez Environment.getExternalStoragePublicDirectory(), kde v parametri uvedieme typ obsahu adresára. Príkladom je Environment.DIRECTORY_DOWNLOADS pre stiahnuté súbory.
    2. súbory určené pre appku zapíšeme do adresára získaného cez 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ť!

Čítanie z externého úložiska

Pre čítanie z úložiska potrebujeme:

  1. získať oprávnenie android.permission.READ_EXTERNAL_STORAGE
  2. 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;
    }
    
  3. 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.