lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Opsi Storage

Android menyediakan beberapa pilihan bagi Anda untuk menyimpan data aplikasi persisten. Solusi yang Anda pilih tergantung pada kebutuhan khusus Anda, seperti apakah data hanya khusus untuk aplikasi Anda atau bisa diakses oleh aplikasi lain (dan penggunanya) dan berapa banyak ruang yang dibutuhkan data.

Pilihan storage data Anda adalah sebagai berikut:

Preferensi Bersama
Menyimpan data primitif pribadi dalam pasangan nilai-kunci.
Penyimpanan Internal
Menyimpan data pribadi pada memori perangkat.
Penyimpanan Eksternal
Menyimpan data publik pada penyimpanan eksternal bersama.
Database SQLite
Menyimpan data terstruktur dalam database pribadi.
Koneksi Jaringan
Menyimpan data pada web dengan server jaringan sendiri.

Android menyediakan cara bagi Anda untuk membuka data pribadi Anda ke aplikasi lain — dengan penyedia materi. Penyedia materi adalah komponen opsional yang membuka akses baca/tulis ke data aplikasi, tunduk pada pembatasan apa pun yang Anda ingin berlakukan. Untuk informasi selengkapnya tentang menggunakan penyedia materi, lihat dokumentasi Penyedia Materi .

Menggunakan Preferensi Bersama

Kelas SharedPreferences menyediakan kerangka kerja umum yang memungkinkan Anda untuk menyimpan dan mengambil pasangan nilai-kunci persisten dari tipe data primitif. Anda bisa menggunakan SharedPreferences untuk menyimpan data primitif: boolean, float, int, long, dan string. Data ini akan terus bertahan di sesi pengguna (bahkan jika aplikasi Anda dimatikan).

Untuk mendapatkan objek SharedPreferences bagi aplikasi Anda, gunakan salah satu dari dua metode berikut:

  • getSharedPreferences() - Gunakan ini jika Anda memerlukan beberapa file preferensi yang diidentifikasi berdasarkan nama, yang Anda tetapkan dengan parameter pertama.
  • getPreferences() - Gunakan ini jika Anda hanya membutuhkan satu file preferensi untuk Aktivitas. Karena ini merupakan satu-satunya file preferensi untuk Aktivitas, Anda tidak memberikan nama.

Untuk menulis nilai:

  1. Panggil edit() untuk mendapat SharedPreferences.Editor.
  2. Tambahkan nilai dengan metode seperti putBoolean() dan putString().
  3. Konfirmasikan nilai-nilai baru dengan commit()

Untuk membaca nilai, gunakan metode SharedPreferences seperti getBoolean() dan getString().

Berikut adalah contoh yang menyimpan preferensi untuk mode penekanan tombol senyap dalam kalkulator:

public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";

    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .

       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }

    @Override
    protected void onStop(){
       super.onStop();

      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);

      // Commit the edits!
      editor.commit();
    }
}

Menggunakan Penyimpanan Internal

Anda bisa menyimpan file secara langsung pada penyimpanan internal perangkat. Secara default, file yang disimpan ke penyimpanan internal adalah privat untuk aplikasi Anda dan aplikasi lain tidak bisa mengaksesnya (begitu juga penggunanya). Bila pengguna mencopot pemasangan aplikasi Anda, file-file ini akan dibuang.

Untuk membuat dan menulis file privat ke penyimpanan internal:

  1. Panggil openFileOutput() dengan nama file dan mode pengoperasian. Proses ini mengembalikan FileOutputStream.
  2. Tulis ke file dengan write().
  3. Tutup aliran dengan close().

Misalnya:

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

MODE_PRIVATE akan membuat file (atau mengganti file dengan nama yang sama) dan membuatnya privat untuk aplikasi Anda. Mode lain yang tersedia adalah: MODE_APPEND, MODE_WORLD_READABLE, dan MODE_WORLD_WRITEABLE.

Catatan: Konstanta MODE_WORLD_READABLE dan MODE_WORLD_WRITEABLE tidak digunakan lagi sejak API level 17. Dimulai dari Android N, penggunaannya akan mengakibatkan SecurityException dikeluarkan. Ini berarti bahwa aplikasi yang menargetkan Android N dan lebih tinggi tidak dapat berbagi file privat berdasar nama, dan upaya untuk berbagi "file://" URI akan mengakibatkan FileUriExposedException dilontarkan. Jika aplikasi Anda perlu berbagi file privat dengan aplikasi lain, aplikasi bisa menggunakan FileProvider dengan FLAG_GRANT_READ_URI_PERMISSION. Lihat juga Berbagi File.

Untuk membaca file dari penyimpanan internal:

  1. Panggil openFileInput() dan memberikannya nama file yang akan dibaca. Proses ini mengembalikan FileInputStream.
  2. Baca byte dari file dengan read().
  3. Kemudian tutup aliran dengan close().

Tip: Jika Anda ingin menyimpan file statis dalam aplikasi Anda pada waktu kompilasi, simpan file tersebut dalam direktori res/raw/ proyek. Anda bisa membukanya dengan openRawResource(), memberikan ID sumber daya R.raw.<filename>. Metode ini mengembalikan sebuah InputStream yang bisa Anda gunakan untuk membaca file (namun Anda tidak bisa menulis ke file aslinya).

Menyimpan file cache

Jika Anda ingin membuat cache beberapa data, daripada menyimpannya secara terus-menerus, Anda sebaiknya menggunakan getCacheDir() untuk membuka File yang mewakili direktori internal tempat aplikasi Anda harus menyimpan file cache sementara.

Bila perangkat hampir kehabisan ruang penyimpanan internal, Android bisa menghapus file cache ini untuk memulihkan ruang. Namun, Anda tidak boleh bergantung pada sistem untuk membersihkan file-file ini. Anda harus selalu mengelola sendiri file cache ini dan menjaga ruang yang digunakan dalam batas wajar, seperti 1MB. Bila pengguna mencopot pemasangan aplikasi Anda, file-file ini akan dibuang.

Metode berguna yang lainnya

getFilesDir()
Mendapatkan jalur absolut ke direktori filesystem tempat file internal Anda disimpan.
getDir()
Membuat (atau membuka yang sudah ada) direktori dalam ruang penyimpanan internal Anda.
deleteFile()
Menghapus file yang disimpan pada penyimpanan internal.
fileList()
Mengembalikan larik file yang sekarang disimpan oleh aplikasi Anda.

Menggunakan Penyimpanan Eksternal

Setiap perangkat kompatibel-Android mendukung "penyimpanan eksternal" bersama yang bisa Anda gunakan untuk menyimpan file. Ini bisa berupa media storage lepas-pasang (seperti kartu SD) atau penyimpanan internal (tidak lepas-pasang). File yang disimpan ke penyimpanan eksternal bisa dibaca oleh semua dan dapat dimodifikasi oleh pengguna ketika mereka mengaktifkan penyimpanan massal USB untuk mentransfer file pada komputer.

Perhatian: Penyimpanan eksternal bisa menjadi tidak tersedia jika pengguna memasang penyimpanan eksternal pada komputer atau membuang media, dan tidak ada keamanan yang diberlakukan pada file yang Anda simpan pada penyimpanan eksternal. Semua aplikasi bisa membaca dan menulis file yang ditempatkan pada penyimpanan eksternal dan pengguna dapat membuangnya.

Menggunakan Scoped Directory Access

Pada Android 7.0 atau yang lebih baru, jika Anda memerlukan akses ke direktori tertentu pada penyimpanan eksternal, gunakan scoped directory access. Scoped directory access menyederhanakan cara aplikasi Anda mengakses direktori penyimpanan eksternal standar, seperti direktori Pictures, dan menyediakan UI izin sederhana yang menjelaskan dengan detail tentang direktori yang dimintai akses oleh aplikasi. Untuk detail selengkapnya tentang scoped directory access, lihat Menggunakan Scoped Directory Access.

Memperoleh akses ke penyimpanan eksternal

Agar bisa membaca atau menulis file pada penyimpanan eksternal, aplikasi Anda harus memperoleh READ_EXTERNAL_STORAGE atau izin sistem WRITE_EXTERNAL_STORAGE . Misalnya:

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

Jika Anda membutuhkan izin baca dan tulis file, maka Anda hanya perlu meminta izin WRITE_EXTERNAL_STORAGE, karena izin ini secara tidak langsung juga memerlukan akses baca.

Catatan: Mulai Android 4.4, izin ini tidak diperlukan jika Anda hanya membaca atau menulis file yang privat untuk aplikasi Anda. Untuk informasi selengkapnya, lihat bagian di bawah tentang menyimpan file privat-aplikasi.

Memeriksa ketersediaan media

Sebelum Anda melakukan sesuatu dengan penyimpanan eksternal, Anda harus selalu memanggil getExternalStorageState() untuk memeriksa apakah media tersebut tersedia. Media tersebut mungkin dipasang di komputer, hilang, hanya-baca, atau dalam status lain. Misalnya, berikut ini adalah beberapa metode yang bisa Anda gunakan untuk memeriksa ketersediaan:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

Metode getExternalStorageState() mengembalikan status-status lain yang mungkin ingin Anda periksa, seperti apakah media sedang dibagikan (terhubung ke komputer), hilang seluruhnya, telah dibuang dengan sembrono, dll. Anda bisa menggunakan ini untuk memberi tahu pengguna dengan lebih banyak informasi ketika aplikasi harus mengakses media.

Menyimpan file yang bisa dibagikan dengan aplikasi lain

Biasanya, file baru yang diperoleh pengguna melalui aplikasi Anda, disimpan ke lokasi "publik" pada perangkat sehingga aplikasi lain bisa mengaksesnya dan pengguna dapat dengan mudah menyalinnya dari perangkat. Bila melakukannya, Anda harus menggunakan salah satu direktori publik bersama, seperti Music/, Pictures/, dan Ringtones/.

Agar File mewakili direktori publik yang tepat, panggil getExternalStoragePublicDirectory(), berikan tipe direktori yang Anda inginkan, seperti DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES, atau lainnya. Dengan menyimpan file ke direktori tipe media yang sesuai, pemindai media sistem bisa dengan benar mengategorikan file Anda ke dalam sistem (misalnya , nada dering muncul dalam setelan sistem sebagai nada dering, bukan sebagai musik).

Misalnya, berikut ini adalah metode yang membuat sebuah direktori untuk album foto baru dalam direktori foto publik:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

Menyimpan file privat-aplikasi

Jika Anda menangani file yang tidak ditujukan untuk digunakan oleh aplikasi lain (seperti tekstur grafis atau efek suara yang hanya digunakan oleh aplikasi Anda), Anda sebaiknya menggunakan direktori penyimpanan privat dalam penyimpanan eksternal dengan memanggil getExternalFilesDir(). Metode ini juga membutuhkan argumen type untuk menentukan tipe subdirektori (seperti DIRECTORY_MOVIES). Jika Anda tidak memerlukan direktori media tertentu, berikan null untuk menerima direktori akar dari direktori privat aplikasi Anda.

Mulai Android 4.4, membaca atau menulis file dalam direktori privat aplikasi tidak memerlukan izin READ_EXTERNAL_STORAGE atau WRITE_EXTERNAL_STORAGE . Jadi Anda bisa mendeklarasikan izin yang seharusnya hanya diminta oleh versi Android yang lebih rendah dengan menambahkan atribut maxSdkVersion :

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     android:maxSdkVersion="18" />
    ...
</manifest>

Catatan: Bila pengguna mencopot pemasangan aplikasi Anda, direktori ini dan semua isinya akan dihapus. Juga, pemindai media sistem tidak membaca file dalam direktori ini, sehingga mereka tidak bisa diakses dari penyedia materi MediaStore. Dengan demikian, Anda sebaiknya tidak menggunakan direktori ini untuk media yang akhirnya menjadi milik pengguna, seperti foto yang dijepret atau diedit dengan aplikasi Anda, atau musik yang telah dibeli pengguna dengan aplikasi—file-file tersebut harus disimpan dalam direktori publik.

Terkadang, sebuah perangkat yang sudah mengalokasikan partisi dari memori internal untuk digunakan sebagai penyimpanan eksternal mungkin juga menawarkan slot kartu SD. Ketika perangkat tersebut menjalankan Android 4.3 dan yang lebih rendah, metode getExternalFilesDir() menyediakan akses hanya ke partisi internal dan aplikasi Anda tidak bisa membaca atau menulis ke kartu SD. Mulai Android 4.4, namun, Anda bisa mengakses kedua lokasi dengan memanggil getExternalFilesDirs(), yang mengembalikan larik File dengan entri setiap lokasi. Entri pertama dalam larik ini adalah penyimpanan eksternal utama dan Anda harus menggunakan lokasi tersebut kecuali itu penuh atau tidak tersedia. Jika Anda ingin mengakses kedua lokasi yang mungkin digunakan tersebut serta juga mendukung Android 4.3 dan yang lebih rendah, gunakan metode statis pustaka dukungan , ContextCompat.getExternalFilesDirs(). Ini juga mengembalikan larik File, namun hanya selalu memuat satu entri pada Android 4.3 dan yang lebih rendah.

Perhatian Meskipun direktori yang disediakan oleh getExternalFilesDir() dan getExternalFilesDirs() tidak bisa diakses oleh penyedia materi MediaStore, aplikasi lain dengan izin READ_EXTERNAL_STORAGE bisa mengakses semua file pada penyimpanan eksternal, termasuk ini. Jika Anda harus benar-benar membatasi akses ke file, Anda sebaiknya menulis file ke penyimpanan internal.

Menyimpan file cache

Untuk membuka File yang mewakili direktori penyimpanan eksternal tempat Anda harus menyimpan file cache, panggil getExternalCacheDir(). Jika pengguna mencopot pemasangan aplikasi Anda, file-file ini akan dihapus secara otomatis.

Mirip dengan ContextCompat.getExternalFilesDirs(), yang disebutkan di atas, Anda juga bisa mengakses direktori cache pada penyimpanan eksternal sekunder (jika tersedia) dengan memanggil ContextCompat.getExternalCacheDirs().

Tip: Untuk menjaga ruangan file dan mempertahankan kinerja aplikasi, Anda harus selalu hati-hati mengelola file cache dan membuang file yang tidak diperlukan lagi dalam daur hidup aplikasi.

Menggunakan Database

Android menyediakan dukungan penuh untuk database SQLite. Setiap database yang Anda buat akan bisa diakses berdasar nama untuk setiap kelas dalam aplikasi, tapi tidak di luar aplikasi.

Metode yang disarankan untuk membuat database SQLite baru adalah dengan membuat subkelas dari SQLiteOpenHelper dan mengganti metode onCreate(), di mana Anda bisa menjalankan perintah SQLite untuk membuat tabel dalam database. Misalnya:

public class DictionaryOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 2;
    private static final String DICTIONARY_TABLE_NAME = "dictionary";
    private static final String DICTIONARY_TABLE_CREATE =
                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
                KEY_WORD + " TEXT, " +
                KEY_DEFINITION + " TEXT);";

    DictionaryOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DICTIONARY_TABLE_CREATE);
    }
}

Anda kemudian bisa mendapatkan instance dari implementasi SQLiteOpenHelper menggunakan konstruktor yang telah Anda tetapkan. Untuk menulis dan membaca dari database, panggil getWritableDatabase() dan getReadableDatabase(). Keduanya mengembalikan objek SQLiteDatabase yang mewakili database dan menyediakan metode untuk operasi SQLite.

Anda bisa menjalankan kueri SQLite menggunakan metode SQLiteDatabase query(), yang menerima berbagai parameter kueri, seperti tabel untuk kueri, proyeksi, seleksi, kolom, pengelompokan, dan lain-lain. Untuk kueri yang kompleks, seperti yang membutuhkan nama alias kolom, Anda sebaiknya menggunakan SQLiteQueryBuilder, yang menyediakan beberapa metode yang mudah untuk membangun kueri.

Setiap kueri SQLite akan mengembalikan Cursor yang menunjuk ke semua baris yang ditemukan oleh kueri. Cursor Adalah mekanisme yang selalu bisa Anda gunakan untuk menavigasi hasil dari kueri database serta membaca baris dan kolom.

Untuk aplikasi contoh yang menunjukkan bagaimana menggunakan database SQLite dalam Android, lihat aplikasi Note Pad dan Searchable Dictionary .

Men-debug database

Android SDK menyertakan alat database sqlite3 yang memungkinkan Anda untuk menjelajah isi tabel, menjalankan perintah SQL, dan melakukan fungsi penting lainnya pada database SQLite. Lihat Menguji database sqlite3 dari shell jauh untuk mempelajari cara menjalankan alat ini.

Menggunakan Koneksi Jaringan

Anda bisa menggunakan jaringan (bila tersedia) untuk menyimpan dan mengambil data pada layanan berbasis web Anda sendiri. Untuk melakukan operasi jaringan, gunakan kelas-kelas dalam paket berikut: