Latar Belakang
Pada Android 4.4 (KitKat), Google telah membatasi akses ke kartu SD.
Mulai Android Lollipop (5.0), pengembang dapat menggunakan API baru yang meminta pengguna mengonfirmasi untuk mengizinkan akses ke folder tertentu, seperti yang tertulis di postingan Google-Grup ini .
Masalah
Pos tersebut mengarahkan Anda untuk mengunjungi dua situs web:
Ini terlihat seperti contoh batin (mungkin akan ditampilkan di demo API nanti), tetapi cukup sulit untuk memahami apa yang sedang terjadi.
Ini adalah dokumentasi resmi dari API baru, tetapi tidak menjelaskan cukup detail tentang cara menggunakannya.
Inilah yang diberitahukannya kepada Anda:
Jika Anda benar-benar membutuhkan akses penuh ke seluruh subpohon dokumen, mulailah dengan meluncurkan ACTION_OPEN_DOCUMENT_TREE untuk memungkinkan pengguna memilih direktori. Kemudian berikan getData () yang dihasilkan ke fromTreeUri (Context, Uri) untuk mulai bekerja dengan pohon yang dipilih pengguna.
Saat Anda menavigasi pohon instance DocumentFile, Anda selalu bisa menggunakan getUri () untuk mendapatkan Uri yang mewakili dokumen yang mendasari objek itu, untuk digunakan dengan openInputStream (Uri), dll.
Untuk menyederhanakan kode Anda pada perangkat yang menjalankan KITKAT atau yang lebih lama, Anda dapat menggunakan fromFile (File) yang meniru perilaku DocumentsProvider.
Pertanyaan-pertanyaan
Saya punya beberapa pertanyaan tentang API baru:
- Bagaimana Anda benar-benar menggunakannya?
- Menurut postingan tersebut, OS akan mengingat bahwa aplikasi tersebut diberi izin untuk mengakses file / folder. Bagaimana Anda memeriksa apakah Anda dapat mengakses file / folder? Apakah ada fungsi yang mengembalikan daftar file / folder yang dapat saya akses?
- Bagaimana Anda menangani masalah ini di Kitkat? Apakah ini bagian dari pustaka dukungan?
- Apakah ada layar pengaturan pada OS yang menunjukkan aplikasi mana yang memiliki akses ke file / folder mana?
- Apa yang terjadi jika aplikasi dipasang untuk beberapa pengguna di perangkat yang sama?
- Apakah ada dokumentasi / tutorial lain tentang API baru ini?
- Bisakah izin dicabut? Jika ya, apakah ada maksud yang dikirim ke aplikasi?
- Apakah meminta izin bekerja secara rekursif pada folder yang dipilih?
- Akankah menggunakan izin juga memungkinkan untuk memberikan kesempatan kepada pengguna untuk melakukan beberapa pilihan berdasarkan pilihan pengguna? Atau apakah aplikasi perlu secara khusus memberi tahu maksud file / folder mana yang diizinkan?
- Apakah ada cara bagi emulator untuk mencoba API baru? Maksud saya, ini memiliki partisi kartu SD, tetapi berfungsi sebagai penyimpanan eksternal utama, jadi semua akses ke sana sudah diberikan (menggunakan izin sederhana).
- Apa yang terjadi jika pengguna mengganti kartu SD dengan yang lain?
sumber
Jawaban:
Banyak pertanyaan bagus, mari kita gali. :)
Bagaimana kamu menggunakannya?
Berikut adalah tutorial bagus untuk berinteraksi dengan Storage Access Framework di KitKat:
https://developer.android.com/guide/topics/providers/document-provider.html#client
Berinteraksi dengan API baru di Lollipop sangat mirip. Untuk meminta pengguna memilih pohon direktori, Anda bisa meluncurkan maksud seperti ini:
Kemudian di onActivityResult (), Anda bisa meneruskan Uri yang dipilih pengguna ke kelas helper DocumentFile baru. Berikut adalah contoh cepat yang mencantumkan file di direktori yang dipilih, lalu membuat file baru:
Uri yang dikembalikan oleh
DocumentFile.getUri()
cukup fleksibel untuk digunakan dengan API platform yang berbeda. Misalnya, Anda dapat membagikannyaIntent.setData()
denganIntent.FLAG_GRANT_READ_URI_PERMISSION
.Jika Anda ingin mengakses Uri tersebut dari kode native, Anda dapat memanggil
ContentResolver.openFileDescriptor()
dan kemudian menggunakanParcelFileDescriptor.getFd()
ataudetachFd()
untuk mendapatkan integer deskriptor file POSIX tradisional.Bagaimana Anda memeriksa apakah Anda dapat mengakses file / folder?
Secara default, Uris yang dikembalikan melalui maksud Storage Access Frameworks tidak dipertahankan selama boot ulang. Platform "menawarkan" kemampuan untuk mempertahankan izin, tetapi Anda masih perlu "mengambil" izin jika Anda menginginkannya. Dalam contoh kami di atas, Anda akan menelepon:
Anda selalu dapat mengetahui hibah tetap yang dapat diakses aplikasi Anda melalui
ContentResolver.getPersistedUriPermissions()
API. Jika Anda tidak lagi memerlukan akses ke Uri yang bertahan, Anda dapat melepaskannya denganContentResolver.releasePersistableUriPermission()
.Apakah ini tersedia di KitKat?
Tidak, kami tidak dapat menambahkan fungsionalitas baru secara retroaktif ke versi platform yang lebih lama.
Dapatkah saya melihat aplikasi apa yang memiliki akses ke file / folder?
Saat ini tidak ada UI yang menunjukkan hal ini, tetapi Anda dapat menemukan detailnya di bagian "Izin Uri yang Diberikan" pada
adb shell dumpsys activity providers
keluaran.Apa yang terjadi jika aplikasi dipasang untuk beberapa pengguna di perangkat yang sama?
Pemberian izin Uri diisolasi per pengguna, sama seperti semua fungsionalitas platform multi-pengguna lainnya. Artinya, aplikasi yang sama yang berjalan di bawah dua pengguna berbeda tidak memiliki izin Uri yang tumpang tindih atau dibagikan.
Bisakah izin dicabut?
DocumentProvider pendukung dapat mencabut izin kapan saja, seperti saat dokumen berbasis Internet dihapus. Cara paling umum untuk menemukan izin yang dicabut ini adalah ketika izin tersebut menghilang dari yang
ContentResolver.getPersistedUriPermissions()
disebutkan di atas.Izin juga dicabut setiap kali data aplikasi dihapus untuk salah satu aplikasi yang terlibat dalam pemberian.
Apakah meminta izin bekerja secara rekursif pada folder yang dipilih?
Ya,
ACTION_OPEN_DOCUMENT_TREE
maksudnya memberi Anda akses rekursif ke file dan direktori yang ada dan yang baru dibuat.Apakah ini memungkinkan banyak pilihan?
Ya, beberapa pilihan telah didukung sejak KitKat, dan Anda bisa mengizinkannya dengan menyetel
EXTRA_ALLOW_MULTIPLE
saat memulaiACTION_OPEN_DOCUMENT
maksud Anda . Anda dapat menggunakanIntent.setType()
atauEXTRA_MIME_TYPES
mempersempit jenis file yang dapat dipilih:http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
Apakah ada cara bagi emulator untuk mencoba API baru?
Ya, perangkat penyimpanan bersama utama seharusnya muncul di alat pilih, bahkan di emulator. Jika aplikasi Anda hanya menggunakan Storage Access Framework untuk mengakses penyimpanan bersama, Anda tidak lagi memerlukan
READ/WRITE_EXTERNAL_STORAGE
izin sama sekali dan dapat menghapusnya atau menggunakanandroid:maxSdkVersion
fitur tersebut untuk hanya memintanya pada versi platform yang lebih lama.Apa yang terjadi ketika pengguna mengganti SD-card dengan yang lain?
Jika media fisik terlibat, UUID (seperti nomor seri FAT) dari media yang mendasarinya selalu dibakar ke Uri yang dikembalikan. Sistem menggunakan ini untuk menghubungkan Anda ke media yang awalnya dipilih pengguna, meskipun pengguna menukar media di antara beberapa slot.
Jika pengguna menukar kartu kedua, Anda harus meminta untuk mendapatkan akses ke kartu baru. Karena sistem mengingat pemberian berdasarkan UUID, Anda akan terus mendapatkan akses yang sebelumnya diberikan ke kartu asli jika pengguna memasukkannya kembali nanti.
http://en.wikipedia.org/wiki/Volume_serial_number
sumber
Dalam proyek Android saya di Github, ditautkan di bawah, Anda dapat menemukan kode kerja yang memungkinkan untuk menulis di extSdCard di Android 5. Ini mengasumsikan bahwa pengguna memberikan akses ke seluruh Kartu SD dan kemudian memungkinkan Anda menulis di mana saja di kartu ini. (Jika Anda ingin memiliki akses hanya ke satu file, segalanya menjadi lebih mudah.)
Snipplet Kode Utama
Memicu Kerangka Akses Penyimpanan:
Menangani respons dari Storage Access Framework:
Mendapatkan outputStream untuk file melalui Storage Access Framework (memanfaatkan URL yang disimpan, dengan asumsi bahwa ini adalah URL dari folder root dari kartu SD eksternal)
Ini menggunakan metode helper berikut:
Referensi ke kode lengkap
https://github.com/jeisfeld/Augendiagnose/blob/master/AugendiagnoseIdea/augendiagnoseLib/src/main/java/de/jeisfeld/augendiagnoselib/fragments/SettingsFragment.java#L521
dan
https://github.com/jeisfeld/Augendiagnose/blob/master/AugendiagnoseIdea/augendiagnoseLib/src/main/java/de/jeisfeld/augendiagnoselib/util/imagefile/FileUtil.java
sumber
File
254 kali. Bisakah Anda bayangkan memperbaikinya ?? Android menjadi mimpi buruk bagi pengembang dengan kurangnya kompatibilitas ke belakang. Saya masih tidak menemukan tempat di mana mereka menjelaskan mengapa Google mengambil semua keputusan bodoh ini terkait penyimpanan eksternal. Beberapa mengklaim "keamanan", tetapi tentu saja tidak masuk akal karena aplikasi apa pun dapat mengacaukan penyimpanan internal. Tebakan saya adalah mencoba memaksa kami menggunakan layanan cloud mereka. Untungnya, rooting memecahkan masalah ... setidaknya untuk Android <6 ....Itu hanyalah jawaban pelengkap.
Setelah Anda membuat file baru, Anda mungkin perlu menyimpan lokasinya ke database Anda dan membacanya besok. Anda dapat membaca mengambilnya lagi menggunakan metode ini:
sumber