Tampilan cepat penyimpanan
- Menggunakan Preferensi Bersama untuk data primitif
- Menggunakan penyimpanan perangkat internal untuk data pribadi
- Menggunakan penyimpanan eksternal untuk kumpulan data besar yang tidak bersifat pribadi
- Menggunakan database SQLite untuk penyimpanan terstruktur
Dalam dokumen ini
- Menggunakan Preferensi Bersama
- Menggunakan Penyimpanan Internal
- Menggunakan Penyimpanan Eksternal
- Menggunakan Database
- Menggunakan Koneksi Jaringan
Lihat juga
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).
Preferensi Pengguna
Preferensi bersama tidak cuma untuk menyimpan "preferensi pengguna," seperti nada dering apa
yang dipilih pengguna. Jika Anda tertarik membuat preferensi pengguna untuk aplikasi, lihat PreferenceActivity, yang menyediakan kerangka kerja Aktivitas bagi Anda untuk membuat
preferensi pengguna, yang akan secara otomatis dipertahankan (menggunakan preferensi bersama).
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:
- Panggil
edit()untuk mendapatSharedPreferences.Editor. - Tambahkan nilai dengan metode seperti
putBoolean()danputString(). - 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:
- Panggil
openFileOutput()dengan nama file dan mode pengoperasian. Proses ini mengembalikanFileOutputStream. - Tulis ke file dengan
write(). - 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:
- Panggil
openFileInput()dan memberikannya nama file yang akan dibaca. Proses ini mengembalikanFileInputStream. - Baca byte dari file dengan
read(). - 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 direktoriPictures, 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
Menyembunyikan file Anda dari Pemindai Media
Memasukkan file kosong bernama .nomedia dalam direktori file eksternal Anda (perhatikan awalan
titik dalam nama file). Hal ini mencegah pemindai media membaca file
media Anda dan memberikannya ke aplikasi lain melalui penyedia materi MediaStore
. Namun, jika file benar-benar privat untuk aplikasi, Anda harus
menyimpannya dalam direktori privat-aplikasi.
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.
Android tidak memaksakan pembatasan apa pun di luar konsep SQLite standar. Kami merekomendasikan
menyertakan bidang kunci nilai autoincrement yang bisa digunakan sebagai ID unik agar bisa
dengan cepat menemukan catatan. Hal ini tidak diperlukan untuk data privat, namun jika Anda
mengimplementasikan penyedia materi,
Anda harus menyertakan ID unik menggunakan konstanta BaseColumns._ID
.
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: