Android 14 memperkenalkan Akses Foto yang Dipilih, yang memungkinkan pengguna memberi aplikasi akses ke gambar dan video tertentu di galeri foto mereka, bukan memberikan akses ke semua media dari jenis tertentu.
Perubahan ini hanya diaktifkan jika aplikasi Anda menargetkan Android 14 (level API 34) atau yang lebih baru. Jika Anda belum menggunakan pemilih foto, sebaiknya terapkan di aplikasi Anda untuk memberikan pengalaman yang konsisten dalam memilih gambar dan video yang juga meningkatkan privasi pengguna tanpa harus meminta izin penyimpanan apa pun.
Jika Anda mengelola pemilih galeri Anda sendiri menggunakan izin penyimpanan dan perlu
mempertahankan kontrol penuh atas implementasi Anda, sesuaikan implementasi Anda
untuk menggunakan izin READ_MEDIA_VISUAL_USER_SELECTED
baru. Jika aplikasi Anda
tidak menggunakan izin baru, sistem akan menjalankan aplikasi Anda dalam mode
kompatibilitas.
SDK Target | READ_MEDIA_VISUAL_USER_SELECTED dideklarasikan |
Akses Foto yang Dipilih diaktifkan | Perilaku UX |
---|---|---|---|
SDK 33 | Tidak | Tidak | T/A |
Ya | Ya | Dikontrol oleh aplikasi | |
SDK 34 | Tidak | Ya | Dikontrol oleh sistem (perilaku kompatibilitas) |
Ya | Ya | Dikontrol oleh aplikasi |
Membuat atau menyesuaikan pemilih galeri Anda sendiri
Membuat pemilih galeri Anda sendiri memerlukan pengembangan dan pemeliharaan yang ekstensif, dan aplikasi Anda perlu meminta izin penyimpanan untuk mendapatkan izin pengguna yang eksplisit. Pengguna dapat menolak permintaan ini atau, jika aplikasi Anda berjalan di perangkat dengan Android 14 dan aplikasi Anda menargetkan Android 14 (level API 34) atau yang lebih tinggi, batasi akses ke media yang dipilih. Gambar berikut menunjukkan contoh permintaan izin dan memilih media menggunakan opsi baru.
Bagian ini menunjukkan pendekatan yang direkomendasikan untuk membuat pemilih galeri
Anda sendiri menggunakan MediaStore
. Jika sudah mengelola pemilih galeri untuk aplikasi
dan perlu mempertahankan kontrol penuh, Anda dapat menggunakan contoh ini untuk menyesuaikan
penerapan. Jika Anda tidak mengupdate penerapan untuk menangani Akses Foto
yang Dipilih, sistem akan menjalankan aplikasi Anda dalam mode kompatibilitas.
Meminta izin
Pertama, minta izin penyimpanan yang benar dalam manifes Android, bergantung pada versi OS:
<!-- Devices running Android 12L (API level 32) or lower -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Devices running Android 13 (API level 33) or higher -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- To handle the reselection within the app on devices running Android 14
or higher if your app targets Android 14 (API level 34) or higher. -->
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
Kemudian, minta izin runtime yang benar, yang juga bergantung pada versi OS:
// Register ActivityResult handler
val requestPermissions = registerForActivityResult(RequestMultiplePermissions()) { results ->
// Handle permission requests results
// See the permission example in the Android platform samples: https://github.com/android/platform-samples
}
// Permission request logic
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissions.launch(arrayOf(READ_MEDIA_IMAGES, READ_MEDIA_VIDEO))
} else {
requestPermissions.launch(arrayOf(READ_EXTERNAL_STORAGE))
}
Beberapa aplikasi tidak memerlukan izin
Mulai Android 10 (level API 29), aplikasi tidak lagi memerlukan izin penyimpanan untuk menambahkan
file ke penyimpanan bersama. Artinya, aplikasi dapat menambahkan gambar ke galeri,
merekam video dan menyimpannya ke penyimpanan bersama, atau mendownload invoice PDF tanpa
harus meminta izin penyimpanan. Jika aplikasi Anda hanya menambahkan file ke penyimpanan
bersama dan tidak membuat kueri gambar atau video, Anda harus berhenti meminta izin
penyimpanan dan menetapkan maxSdkVersion
API 28 di AndroidManifest.xml
:
<!-- No permission is needed to add files to shared storage on Android 10 (API level 29) or higher -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
Menangani pemilihan ulang media
Dengan fitur Akses Foto yang Dipilih di Android 14, aplikasi Anda harus mengadopsi
izin READ_MEDIA_VISUAL_USER_SELECTED
baru untuk mengontrol pemilihan ulang
media, dan mengupdate antarmuka aplikasi agar pengguna dapat memberikan akses
ke kumpulan gambar dan video yang berbeda ke aplikasi Anda. Gambar berikut menunjukkan contoh
permintaan izin dan pemilihan ulang media:
Saat membuka dialog pilihan, foto, video, atau keduanya akan ditampilkan bergantung
pada izin yang diminta. Misalnya, jika Anda meminta
izin READ_MEDIA_VIDEO
tanpa izin READ_MEDIA_IMAGES
, hanya
video yang akan muncul di UI agar pengguna dapat memilih file.
// Allow the user to select only videos
requestPermissions.launch(arrayOf(READ_MEDIA_VIDEO, READ_MEDIA_VISUAL_USER_SELECTED))
Anda dapat memeriksa apakah aplikasi memiliki akses penuh, sebagian, atau ditolak ke galeri foto
perangkat dan mengupdate antarmuka. Minta izin ini
saat aplikasi memerlukan akses penyimpanan, bukan saat dimulai. Perhatikan bahwa
pemberian izin dapat diubah di antara callback siklus proses aplikasi
onStart
dan onResume
, karena pengguna dapat mengubah akses di setelan tanpa
menutup aplikasi Anda.
if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
(
ContextCompat.checkSelfPermission(context, READ_MEDIA_IMAGES) == PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(context, READ_MEDIA_VIDEO) == PERMISSION_GRANTED
)
) {
// Full access on Android 13 (API level 33) or higher
} else if (
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
ContextCompat.checkSelfPermission(context, READ_MEDIA_VISUAL_USER_SELECTED) == PERMISSION_GRANTED
) {
// Partial access on Android 14 (API level 34) or higher
} else if (ContextCompat.checkSelfPermission(context, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
// Full access up to Android 12 (API level 32)
} else {
// Access denied
}
Membuat kueri library perangkat
Setelah memverifikasi bahwa Anda memiliki akses ke izin penyimpanan yang tepat, Anda dapat
berinteraksi dengan MediaStore
untuk membuat kueri library perangkat (pendekatan yang sama berlaku
baik akses yang diberikan bersifat sebagian maupun penuh):
data class Media(
val uri: Uri,
val name: String,
val size: Long,
val mimeType: String,
)
// Run the querying logic in a coroutine outside of the main thread to keep the app responsive.
// Keep in mind that this code snippet is querying only images of the shared storage.
suspend fun getImages(contentResolver: ContentResolver): List<Media> = withContext(Dispatchers.IO) {
val projection = arrayOf(
Images.Media._ID,
Images.Media.DISPLAY_NAME,
Images.Media.SIZE,
Images.Media.MIME_TYPE,
)
val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Query all the device storage volumes instead of the primary only
Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
} else {
Images.Media.EXTERNAL_CONTENT_URI
}
val images = mutableListOf<Media>()
contentResolver.query(
collectionUri,
projection,
null,
null,
"${Images.Media.DATE_ADDED} DESC"
)?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(Images.Media._ID)
val displayNameColumn = cursor.getColumnIndexOrThrow(Images.Media.DISPLAY_NAME)
val sizeColumn = cursor.getColumnIndexOrThrow(Images.Media.SIZE)
val mimeTypeColumn = cursor.getColumnIndexOrThrow(Images.Media.MIME_TYPE)
while (cursor.moveToNext()) {
val uri = ContentUris.withAppendedId(collectionUri, cursor.getLong(idColumn))
val name = cursor.getString(displayNameColumn)
val size = cursor.getLong(sizeColumn)
val mimeType = cursor.getString(mimeTypeColumn)
val image = Media(uri, name, size, mimeType)
images.add(image)
}
}
return@withContext images
}
Cuplikan kode ini disederhanakan untuk menggambarkan cara berinteraksi dengan MediaStore
.
Dalam aplikasi yang siap produksi, gunakan penomoran halaman dengan sesuatu seperti library
Paging untuk membantu memastikan performa yang baik.
Buat kueri pilihan terakhir
Aplikasi di Android 15+ dan Android 14 dengan dukungan update sistem Google Play dapat
mengkueri pilihan terakhir gambar dan video yang dibuat oleh pengguna pada akses parsial
dengan mengaktifkan QUERY_ARG_LATEST_SELECTION_ONLY
:
if (getExtensionVersion(Build.VERSION_CODES.U) >= 12) {
val queryArgs = bundleOf(
QUERY_ARG_SQL_SORT_ORDER to "${Images.Media.DATE_ADDED} DESC"
QUERY_ARG_LATEST_SELECTION_ONLY to true
)
contentResolver.query(collectionUri, projection, queryArgs, null)
}
Akses foto dan video tetap dipertahankan saat perangkat diupgrade
Jika aplikasi Anda berada di perangkat yang diupgrade dari versi Android sebelumnya ke Android 14, sistem akan memiliki akses penuh ke foto dan video pengguna, serta memberikan beberapa izin ke aplikasi Anda secara otomatis. Perilaku yang tepat bergantung pada sekumpulan izin yang diberikan ke aplikasi Anda sebelum perangkat diupgrade ke Android 14.
Izin dari Android 13
Pertimbangkan situasi berikut:
- Aplikasi Anda diinstal di perangkat yang menjalankan Android 13.
- Pengguna telah memberikan izin
READ_MEDIA_IMAGES
dan izinREAD_MEDIA_VIDEO
ke aplikasi Anda. - Perangkat kemudian diupgrade ke Android 14 saat aplikasi Anda masih terinstal.
- Aplikasi Anda mulai menargetkan Android 14 (API level 34) atau yang lebih tinggi.
Dalam hal ini, aplikasi Anda masih memiliki akses penuh ke foto dan video pengguna.
Sistem juga mempertahankan izin READ_MEDIA_IMAGES
dan READ_MEDIA_VIDEO
yang diberikan ke aplikasi Anda secara otomatis.
Izin dari Android 12 dan yang lebih rendah
Pertimbangkan situasi berikut:
- Aplikasi Anda diinstal di perangkat yang menjalankan Android 13.
- Pengguna telah memberikan izin
READ_EXTERNAL_STORAGE
atau izinWRITE_EXTERNAL_STORAGE
ke aplikasi Anda. - Perangkat kemudian diupgrade ke Android 14 saat aplikasi Anda masih terinstal.
- Aplikasi Anda mulai menargetkan Android 14 (API level 34) atau yang lebih tinggi.
Dalam hal ini, aplikasi Anda masih memiliki akses penuh ke foto dan video pengguna.
Sistem juga memberikan izin READ_MEDIA_IMAGES
dan
izin READ_MEDIA_VIDEO
ke aplikasi Anda secara otomatis.
Praktik terbaik
Bagian ini berisi beberapa praktik terbaik untuk menggunakan
izin READ_MEDIA_VISUAL_USER_SELECTED
. Untuk informasi selengkapnya, lihat
praktik terbaik izin kami.
Jangan simpan status izin secara permanen
Jangan simpan status izin secara permanen, termasuk
SharedPreferences
atau DataStore
. Status yang disimpan mungkin tidak disinkronkan dengan
status sebenarnya. Status izin dapat berubah setelah reset izin,
hibernasi aplikasi, perubahan yang dimulai pengguna di setelan aplikasi Anda, atau ketika
aplikasi beralih ke latar belakang. Sebagai gantinya, periksa izin penyimpanan menggunakan
ContextCompat.checkSelfPermission()
.
Jangan berasumsi memiliki akses penuh ke foto dan video
Berdasarkan perubahan yang diperkenalkan di Android 14, aplikasi Anda mungkin hanya memiliki
akses sebagian ke galeri foto perangkat. Jika aplikasi meng-cache data MediaStore
saat dikueri menggunakan ContentResolver
, cache tersebut mungkin tidak diperbarui.
- Selalu buat kueri
MediaStore
menggunakanContentResolver
, bukan mengandalkan cache yang disimpan. - Simpan hasilnya di memori saat aplikasi Anda berada di latar depan.
- Muat ulang hasil saat aplikasi Anda melalui siklus proses aplikasi
onResume
karena pengguna mungkin beralih dari akses penuh ke akses sebagian melalui setelan izin.
Perlakukan akses URI sebagai sementara
Jika pengguna memilih Pilih foto dan video dalam dialog
izin sistem, akses aplikasi Anda ke foto dan video yang dipilih tidak akan berlaku lagi
pada akhirnya.
Aplikasi Anda harus selalu menangani kasus ketika tidak memiliki akses ke Uri
apa pun, terlepas dari otoritasnya.
Memfilter jenis media yang dapat dipilih menurut izin
Dialog pilihan sensitif dengan jenis izin yang diminta:
- Meminta hanya
READ_MEDIA_IMAGES
hanya akan menampilkan gambar yang dapat dipilih. - Meminta hanya
READ_MEDIA_VIDEO
akan menampilkan hanya video yang dapat dipilih. - Meminta
READ_MEDIA_IMAGES
danREAD_MEDIA_VIDEO
akan menampilkan seluruh galeri foto yang dapat dipilih.
Berdasarkan kasus penggunaan aplikasi, Anda harus memastikan untuk meminta izin
yang tepat untuk menghindari pengalaman pengguna yang buruk. Jika fitur hanya mengharapkan
video dipilih, pastikan untuk hanya meminta READ_MEDIA_VIDEO
.
Meminta izin dalam satu operasi
Untuk mencegah pengguna melihat beberapa kotak dialog runtime sistem, minta
izin READ_MEDIA_VISUAL_USER_SELECTED
, ACCESS_MEDIA_LOCATION
, dan "baca media"
(READ_MEDIA_IMAGES
, READ_MEDIA_VIDEO
, atau keduanya) dalam sebuah
operasi.
Mengizinkan pengguna mengelola pilihan mereka
Saat pengguna memilih mode akses sebagian, aplikasi Anda tidak boleh mengasumsikan bahwa library foto perangkat kosong, dan harus mengizinkan pengguna memberikan lebih banyak file.
Pengguna dapat memutuskan untuk beralih dari akses penuh ke akses sebagian melalui setelan izin tanpa memberikan akses ke beberapa file media visual.
Mode kompatibilitas
Jika Anda mengelola pemilih galeri Anda sendiri menggunakan izin penyimpanan, tetapi belum
menyesuaikan aplikasi untuk menggunakan izin READ_MEDIA_VISUAL_USER_SELECTED
baru, sistem akan menjalankan aplikasi dalam mode kompatibilitas setiap kali pengguna
perlu memilih atau memilih ulang media.
Perilaku selama pemilihan media awal
Selama pemilihan awal, jika pengguna memilih "Pilih foto dan video" (lihat
gambar 1), izin READ_MEDIA_IMAGES
dan READ_MEDIA_VIDEO
akan diberikan selama sesi aplikasi, yang memberikan pemberian izin sementara dan
akses sementara ke foto dan video yang dipilih pengguna. Saat aplikasi Anda berpindah ke
latar belakang, atau saat pengguna secara aktif menghentikan aplikasi Anda, sistem pada akhirnya
akan menolak izin ini. Perilaku ini seperti izin satu kali lainnya.
Perilaku selama pemilihan ulang media
Jika aplikasi Anda memerlukan akses ke foto dan video tambahan di lain waktu, Anda
harus meminta izin READ_MEDIA_IMAGES
atau
izin READ_MEDIA_VIDEO
lagi secara manual. Sistem mengikuti alur yang sama seperti
permintaan izin awal, yang meminta pengguna untuk memilih foto dan video (lihat
gambar 2).
Jika aplikasi Anda mengikuti praktik terbaik izin, perubahan ini tidak akan
merusak aplikasi Anda. Hal ini terutama berlaku jika aplikasi Anda tidak berasumsi bahwa akses
URI dipertahankan, menyimpan status izin sistem, atau memuat ulang kumpulan
gambar yang ditampilkan setelah izin berubah. Namun, perilaku ini mungkin tidak
ideal, bergantung pada kasus penggunaan aplikasi Anda. Untuk membantu memberikan pengalaman terbaik
bagi pengguna, sebaiknya terapkan pemilih foto atau sesuaikan pemilih galeri
aplikasi Anda untuk menangani perilaku ini secara langsung menggunakan
izin READ_MEDIA_VISUAL_USER_SELECTED
.