Kasus penggunaan dan praktik terbaik penyimpanan Android

Untuk memberi pengguna kontrol yang lebih besar pada file dan membatasi file yang tidak berfungsi, Android 10 memperkenalkan model penyimpanan baru untuk aplikasi yang disebut penyimpanan terbatas. Penyimpanan terbatas mengubah cara aplikasi menyimpan dan mengakses file di penyimpanan eksternal perangkat. Untuk membantu Anda memigrasikan aplikasi guna mendukung penyimpanan terbatas, ikuti praktik terbaik untuk kasus penggunaan penyimpanan umum yang dijelaskan dalam panduan ini. Kasus penggunaan disusun dalam dua kategori: menangani file media dan menangani file non-media.

Untuk mempelajari lebih lanjut cara menyimpan dan mengakses file di Android, lihat panduan pelatihan penyimpanan.

Menangani file media

Bagian ini menjelaskan beberapa kasus penggunaan umum untuk menangani file media (file video, gambar, dan audio) serta menjelaskan pendekatan tingkat tinggi yang dapat digunakan aplikasi Anda. Tabel berikut meringkas setiap kasus penggunaan tersebut, dan menautkan ke setiap bagian yang berisi detail lebih lanjut.

Kasus penggunaan Ringkasan
Menampilkan semua file gambar atau video Gunakan pendekatan yang sama untuk semua versi Android.
Menampilkan gambar atau video dari folder tertentu Gunakan pendekatan yang sama untuk semua versi Android.
Mengakses informasi lokasi dari foto Gunakan satu pendekatan jika aplikasi Anda menggunakan penyimpanan terbatas. Gunakan pendekatan lain jika aplikasi memilih untuk tidak menggunakan penyimpanan terbatas.
Menentukan lokasi penyimpanan untuk download baru Gunakan satu pendekatan jika aplikasi Anda menggunakan penyimpanan terbatas. Gunakan pendekatan lain jika aplikasi memilih untuk tidak menggunakan penyimpanan terbatas.
Mengekspor file media pengguna ke perangkat Gunakan pendekatan yang sama untuk semua versi Android.
Memodifikasi atau menghapus beberapa file media dalam satu operasi Gunakan satu pendekatan untuk Android 11. Untuk Android 10, pilih untuk tidak menggunakan penyimpanan terbatas dan sebagai gantinya, gunakan pendekatan untuk Android 9 dan yang lebih rendah.
Mengimpor satu gambar yang sudah ada Gunakan pendekatan yang sama untuk semua versi Android.
Mengambil satu gambar Gunakan pendekatan yang sama untuk semua versi Android.
Berbagi file media dengan aplikasi lain Gunakan pendekatan yang sama untuk semua versi Android.
Berbagi file media dengan aplikasi tertentu Gunakan pendekatan yang sama untuk semua versi Android.
Mengakses file dari kode atau library yang menggunakan jalur file langsung Gunakan satu pendekatan untuk Android 11. Untuk Android 10, pilih untuk tidak menggunakan penyimpanan terbatas dan sebagai gantinya, gunakan pendekatan untuk Android 9 dan yang lebih rendah.

Menampilkan file gambar atau video dari beberapa folder

Buat kueri koleksi media menggunakan query() API. Untuk memfilter atau mengurutkan file media, sesuaikan parameter projection, selection, selectionArgs, dan sortOrder.

Menampilkan gambar atau video dari folder tertentu

Gunakan pendekatan ini:

  1. Dengan mengikuti praktik terbaik yang dijelaskan dalam Meminta Izin Aplikasi, minta izin READ_EXTERNAL_STORAGE.
  2. Mengambil file media berdasarkan nilai MediaColumns.DATA, yang berisi jalur sistem file absolut ke item media pada disk.

Catatan: Saat mengakses file media yang ada, Anda dapat menggunakan nilai kolom DATA dalam logika Anda. Itu karena nilai ini memiliki jalur file yang valid. Namun, jangan berasumsi bahwa file tersebut selalu tersedia. Bersiaplah untuk menangani setiap error I/O berbasis file yang dapat terjadi.

Di sisi lain, jangan gunakan kolom DATA untuk membuat atau memperbarui file media. Sebagai gantinya, gunakan kolom DISPLAY_NAME dan RELATIVE_PATH.

Mengakses informasi lokasi dari foto

Jika aplikasi Anda menggunakan penyimpanan terbatas, ikuti langkah-langkah di bagian Informasi lokasi di foto dalam panduan penyimpanan media.

Menentukan lokasi penyimpanan untuk download baru

Jika aplikasi Anda menggunakan penyimpanan terbatas, perhatikan lokasi tempat Anda memilih untuk menyimpan file media yang didownload.

Jika aplikasi lain memerlukan akses ke file, sebaiknya gunakan koleksi media yang ditentukan dengan baik untuk download atau koleksi dokumen.

Di Android 11 dan yang lebih tinggi, file di dalam direktori khusus aplikasi eksternal tidak dapat diakses oleh aplikasi lain meskipun Anda menggunakan DownloadManager untuk mengambil file tersebut.

Mengekspor file media pengguna ke perangkat

Tentukan lokasi default yang tepat untuk menyimpan file media pengguna:

Mengubah atau menghapus beberapa file media dalam satu operasi

Sertakan logika berdasarkan versi Android yang digunakan aplikasi Anda.

Berjalan di Android 11

Gunakan pendekatan ini:

  1. Buat intent yang tertunda untuk permintaan tulis atau hapus permintaan menggunakan MediaStore.createWriteRequest() atau MediaStore.createTrashRequest(), lalu minta pengguna izin untuk mengedit serangkaian file dengan memanggil intent tersebut.
  2. Evaluasi respons pengguna:

    • Jika izin diberikan, lanjutkan dengan memodifikasi atau menghapus operasi.
    • Jika izin tidak diberikan, jelaskan kepada pengguna alasan fitur di aplikasi Anda memerlukan izin.

Pelajari lebih lanjut cara mengelola grup file media menggunakan metode ini yang tersedia di Android 11 dan yang lebih tinggi.

Berjalan di Android 10

Jika aplikasi Anda menargetkan Android 10 (level API 29), pilih untuk tidak menggunakan penyimpanan terbatas dan lanjutkan menggunakan pendekatan untuk Android 9 dan yang lebih rendah untuk menjalankan operasi ini.

Berjalan di Android 9 atau yang lebih rendah

Gunakan pendekatan ini:

  1. Dengan mengikuti praktik terbaik yang dijelaskan dalam Meminta Izin Aplikasi, minta izin WRITE_EXTERNAL_STORAGE.
  2. Gunakan MediaStore API untuk memodifikasi atau menghapus file media.

Mengimpor satu gambar yang sudah ada

Saat Anda ingin mengimpor satu gambar yang sudah ada (misalnya, untuk digunakan sebagai foto untuk profil pengguna), aplikasi Anda dapat menggunakan UI-nya sendiri untuk operasi, atau menggunakan pemilih sistem.

Menyajikan antarmuka pengguna Anda sendiri

Gunakan pendekatan ini:

  1. Dengan mengikuti praktik terbaik yang dijelaskan dalam Meminta Izin Aplikasi, minta izin READ_EXTERNAL_STORAGE.
  2. Gunakan query() API untuk membuat kueri koleksi media.
  3. Tampilkan hasil di UI kustom aplikasi Anda.

Menggunakan alat pilih sistem

Gunakan intent ACTION_GET_CONTENT, yang meminta pengguna memilih gambar untuk diimpor.

Jika Anda ingin memfilter jenis gambar yang ditampilkan oleh pemilih sistem kepada pengguna, Anda dapat menggunakan setType() atau EXTRA_MIME_TYPES.

Mengambil satu gambar

Saat Anda ingin mengambil satu gambar untuk digunakan di aplikasi (misalnya, untuk digunakan sebagai foto profil pengguna), gunakan intent ACTION_IMAGE_CAPTURE untuk meminta pengguna mengambil foto menggunakan kamera perangkat. Sistem menyimpan foto yang diambil di tabel MediaStore.Images.

Berbagi file media dengan aplikasi lain

Gunakan metode insert() untuk menambahkan record secara langsung ke MediaStore. Untuk informasi selengkapnya, lihat bagian Menambahkan item dari panduan penyimpanan media.

Berbagi file media dengan aplikasi tertentu

Gunakan komponen FileProvider Android, seperti yang dijelaskan dalam panduan Menyiapkan berbagi file.

Mengakses file dari kode atau library yang menggunakan jalur file langsung

Sertakan logika berdasarkan versi Android yang digunakan aplikasi Anda.

Berjalan di Android 11

Gunakan pendekatan ini:

  1. Dengan mengikuti praktik terbaik yang dijelaskan dalam Meminta Izin Aplikasi, minta izin READ_EXTERNAL_STORAGE.
  2. Akses file menggunakan jalur file langsung.

Untuk mengetahui informasi selengkapnya, lihat bagian cara membuka file media menggunakan jalur file langsung.

Berjalan di Android 10

Jika aplikasi Anda menargetkan Android 10 (level API 29), pilih untuk tidak menggunakan penyimpanan terbatas dan lanjutkan menggunakan pendekatan untuk Android 9 dan yang lebih rendah untuk menjalankan operasi ini.

Berjalan di Android 9 atau yang lebih rendah

Gunakan pendekatan ini:

  1. Dengan mengikuti praktik terbaik yang dijelaskan dalam Meminta Izin Aplikasi, minta izin WRITE_EXTERNAL_STORAGE.
  2. Akses file menggunakan jalur file langsung.

Menangani file non-media

Bagian ini menjelaskan beberapa kasus penggunaan umum untuk menangani file non-media dan menjelaskan pendekatan tingkat tinggi yang dapat digunakan aplikasi Anda. Tabel berikut meringkas setiap kasus penggunaan tersebut, dan menautkan ke setiap bagian yang berisi detail lebih lanjut.

Kasus penggunaan Ringkasan
Membuka file dokumen Gunakan pendekatan yang sama untuk semua versi Android.
Menulis pada file di volume penyimpanan sekunder Gunakan satu pendekatan untuk Android 11. Untuk versi Android sebelumnya, gunakan pendekatan yang berbeda.
Memigrasikan file yang ada dari lokasi penyimpanan lama Migrasikan file Anda ke penyimpanan terbatas jika memungkinkan. Pilih tidak menggunakan penyimpanan terbatas untuk Android 10 jika diperlukan.
Berbagi konten dengan aplikasi lain Gunakan pendekatan yang sama untuk semua versi Android.
Meng-cache file non-media Gunakan pendekatan yang sama untuk semua versi Android.
Mengekspor file non-media ke perangkat Gunakan satu pendekatan jika aplikasi Anda menggunakan penyimpanan terbatas. Gunakan pendekatan lain jika aplikasi memilih untuk tidak menggunakan penyimpanan terbatas.

Membuka file dokumen

Gunakan intent ACTION_OPEN_DOCUMENT untuk meminta pengguna memilih file untuk dibuka menggunakan pemilih sistem. Jika Anda ingin memfilter jenis file yang akan ditampilkan oleh alat pilih sistem kepada pengguna, Anda dapat menggunakan setType() atau EXTRA_MIME_TYPES.

Misalnya, Anda dapat menemukan semua file PDF, SQL, dan TXT menggunakan kode berikut:

Kotlin

startActivityForResult(
        Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "*/*"
            putExtra(Intent.EXTRA_MIME_TYPES, arrayOf(
                    "application/pdf", // .pdf
                    "application/vnd.oasis.opendocument.text", // .odt
                    "text/plain" // .txt
            ))
        },
        REQUEST_CODE
      )

Java

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] {
                "application/pdf", // .pdf
                "application/vnd.oasis.opendocument.text", // .odt
                "text/plain" // .txt
        });
        startActivityForResult(intent, REQUEST_CODE);

Menulis pada file di volume penyimpanan sekunder

Volume penyimpanan sekunder meliputi kartu SD. Anda dapat mengakses informasi tentang volume penyimpanan tertentu menggunakan class StorageVolume.

Sertakan logika berdasarkan versi Android yang digunakan aplikasi Anda.

Berjalan di Android 11

Gunakan pendekatan ini:

  1. Gunakan model penyimpanan terbatas.
  2. Targetkan Android 10 (level API 29) atau yang lebih rendah.
  3. Menyatakan izin WRITE_EXTERNAL_STORAGE.
  4. Lakukan salah satu jenis akses berikut:
    • Akses file menggunakan MediaStore API.
    • Akses jalur file langsung menggunakan API seperti File atau fopen().

Berjalan di versi lama

Gunakan Storage Access Framework agar pengguna dapat memilih lokasi di volume penyimpanan sekunder tempat aplikasi menulis file tersebut.

Memigrasikan file yang sudah ada dari lokasi penyimpanan lama

Direktori dianggap sebagai lokasi penyimpanan lama jika bukan direktori khusus aplikasi atau direktori bersama publik. Jika aplikasi Anda membuat atau menggunakan file di lokasi penyimpanan lama, sebaiknya Anda memigrasikan file aplikasi ke lokasi yang dapat diakses dengan penyimpanan terbatas dan membuat perubahan aplikasi yang diperlukan untuk bekerja dengan file dalam cakupan yang terbatas.

Mempertahankan akses ke lokasi penyimpanan lama untuk migrasi data

Aplikasi Anda perlu mempertahankan akses ke lokasi penyimpanan lama untuk memigrasikan file aplikasi apa pun ke lokasi yang dapat diakses dengan penyimpanan terbatas. Pendekatan yang harus Anda gunakan bergantung pada level API target aplikasi Anda.

Jika aplikasi Anda menargetkan Android 11
  1. Tetapkan tanda preserveLegacyExternalStorage ke true untuk mempertahankan model penyimpanan lama agar aplikasi Anda dapat memigrasikan data pengguna saat melakukan upgrade ke versi baru aplikasi yang menargetkan Android 11.

  2. Lanjutkan untuk memilih tidak menggunakan penyimpanan terbatas sehingga aplikasi Anda dapat terus mengakses file di lokasi penyimpanan lama pada perangkat Android 10.

Jika aplikasi Anda menargetkan Android 10

Memilih tidak menggunakan penyimpanan terbatas memudahkan Anda menjaga perilaku aplikasi di berbagai versi Android.

Memigrasikan data aplikasi

Saat aplikasi Anda siap dimigrasikan, gunakan pendekatan berikut:

  1. Menargetkan Android 10 atau yang lebih rendah.
  2. Memilih tidak menggunakan penyimpanan terbatas agar aplikasi memiliki akses ke file yang perlu dimigrasikan.
  3. Deploy kode yang menggunakan File API untuk memindahkan file dari lokasinya saat ini pada /sdcard/ ke lokasi yang dapat diakses dengan penyimpanan terbatas:

    1. Pindahkan file aplikasi pribadi ke direktori yang ditampilkan oleh metode getExternalFilesDir().
    2. Pindahkan file non-media bersama ke subdirektori khusus aplikasi dari direktori Downloads/.
  4. Hapus direktori penyimpanan lama aplikasi Anda dari direktori /sdcard/.

Setelah menginstal versi baru aplikasi, pengguna harus menyelesaikan proses migrasi data di perangkatnya. Anda dapat memantau proses migrasi di seluruh basis pengguna dengan membuat peristiwa analisis.

Setelah pengguna memigrasikan data, publikasikan update lain ke aplikasi Anda yang menargetkan Android 11.

Berbagi konten dengan aplikasi lain

Untuk berbagi file aplikasi dengan satu aplikasi lainnya, gunakan FileProvider. Untuk semua aplikasi yang perlu saling berbagi file, sebaiknya gunakan penyedia konten untuk setiap aplikasi, lalu sinkronkan data saat aplikasi ditambahkan ke koleksi.

Meng-cache file non-media

Pendekatan yang harus Anda gunakan bergantung pada jenis file yang perlu di-cache.

Mengekspor file non-media ke perangkat

Tentukan lokasi default yang tepat untuk menyimpan file non-media: Izinkan pengguna mengekspor file dari direktori khusus aplikasi ke lokasi yang dapat diakses secara lebih umum. Gunakan download atau koleksi dokumen MediaStore untuk mengekspor file non-media ke perangkat.

Memilih tidak menggunakan penyimpanan terbatas untuk sementara

Sebelum aplikasi kompatibel sepenuhnya dengan penyimpanan terbatas, Anda dapat sementara waktu menghentikannya, baik dalam pengujian maupun dalam aplikasi produksi.

Memilih tidak ikut dalam pengujian

Di Android 10 (level API 29) dan yang lebih tinggi, pengujian aplikasi berjalan di sandbox penyimpanan secara default. Sandbox ini mencegah aplikasi mengakses file di luar direktori khusus aplikasi dan direktori yang dibagikan secara publik.

Jika pengujian menghasilkan file untuk host—seperti screenshot, data proses debug, data cakupan, atau metrik performa—Anda dapat menulis file ini ke direktori global. Untuk melakukannya, tambahkan tanda berikut ke harness relevan yang mengaktifkan am instrument:

-e no-isolated-storage 1

Tanda ini memengaruhi semua perilaku kasus pengujian berinstrumen dan juga memengaruhi semua kode pengujian yang diaktifkan. Oleh karena itu, saat menggunakan tanda ini, Anda tidak dapat memvalidasi kompatibilitas aplikasi dengan penyimpanan terbatas. Untuk output pengujian, sebaiknya tulis ke penyimpanan yang dibatasi aplikasi yang dapat dibaca oleh shell. Selanjutnya, Anda dapat menarik direktori yang dibatasi aplikasi tersebut. Untuk menentukan direktori mana yang akan diambil, panggil getExternalMediaDirs().

Memilih tidak ikut di aplikasi produksi

Jika aplikasi menargetkan Android 10 (level API 29) atau yang lebih rendah, Anda dapat sementara waktu menghentikan penyimpanan terbatas di aplikasi produksi. Namun, jika menargetkan Android 10, Anda perlu menetapkan nilai requestLegacyExternalStorage ke true dalam file manifes aplikasi:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Untuk menguji perilaku aplikasi yang menargetkan Android 10 atau yang lebih rendah saat menggunakan penyimpanan terbatas, Anda dapat memilih untuk menggunakan perilaku ini dengan menetapkan nilai requestLegacyExternalStorage ke false. Jika melakukan pengujian di perangkat yang menjalankan Android 11, Anda juga dapat menggunakan tanda kompatibilitas aplikasi untuk menguji perilaku aplikasi dengan atau tanpa penyimpanan terbatas.

Referensi lainnya

Untuk informasi penyimpanan Android selengkapnya, lihat materi berikut:

Postingan blog