Perbedaan antara getExternalFilesDir dan getExternalStorageDirectory ()

90

Saya memahami bahwa ExternalFiles akan digunakan pada API 8 dan yang lebih baru dan getExternalStorageDirectory untuk 7 dan ke bawah. Namun saya agak bingung antara penggunaannya. Misalnya saya ingin memeriksa bahwa folder itu ada dan sebelumnya Anda akan menggunakan sesuatu seperti:

File ChildFolder = new File(Environment.getExternalStorageDirectory() + "/ParentFolder/Child");

Namun setiap contoh yang saya lihat mengatakan untuk menggunakan getExternalFilesDir (null), File.ext. Karena saya di atas API 8, saya ingin menggunakan metode ini, tetapi bagaimana cara memeriksa folder? Saya akan memeriksa keberadaan file di titik lain tetapi untuk saat ini hanya ingin melihat apakah foldernya ada ??

GPGVM
sumber

Jawaban:

133
getExternalFilesDir()

Ini mengembalikan jalur ke folder file di dalam Android / data / data / your_package / pada kartu SD Anda. Ini digunakan untuk menyimpan file yang diperlukan untuk aplikasi Anda (mis. Gambar yang diunduh dari web atau file cache). Setelah aplikasi dicopot, semua data yang disimpan di folder ini juga hilang.

getExternalStorageDirectory()

Ini mengembalikan jalur root ke kartu SD Anda (misalnya mnt / sdcard / ). Jika Anda menyimpan data di jalur ini dan mencopot pemasangan aplikasi, data itu tidak akan hilang.

waqaslam
sumber
4
Google Android ingin Anda menggunakan apa pun yang mereka sediakan dalam kerangka kerja. Jadi terserah pilihan dan persyaratan desain Anda. Jika Anda tidak ingin file tetap tersisa saat aplikasi dicopot, Anda disarankan untuk menggunakan getExternalFilesDir () atau getExternalCacheDir ()
waqaslam
5
Ini karena di API 8, mereka memperkenalkan fitur pemindai media canggih yang memungkinkan untuk memindai data dari folder seperti musik, gambar, nada dering, dll. Direktori tersebut dibuat secara otomatis hanya jika Anda menggunakan getExternalFilesDir () . Sekarang karena fitur ini tidak tersedia di API 7, itulah mengapa mereka merekomendasikan untuk menggunakan getExternalStorageDirectory () . Sederhana ...
waqaslam
2
tidak apa-apa, beri waktu, sebentar lagi akan ada momen eureka :)
waqaslam
3
Sangat penting untuk mengetahui bahwa getExternalStorageDirectory()tidak tidak selalu - bahkan mungkin tidak biasanya - "path ke kartu SD Anda" kembali Sebagai gantinya, ia mengembalikan "direktori penyimpanan eksternal primer". Dokumen ( developer.android.com/reference/android/os/… ) mengatakan:
LarsH
2
'Catatan: jangan bingung dengan kata "eksternal" di sini. Direktori ini lebih baik dianggap sebagai media / penyimpanan bersama. Ini adalah sistem file yang dapat menampung data dalam jumlah yang relatif besar dan dibagikan ke semua aplikasi (tidak memberlakukan izin). Secara tradisional ini adalah kartu SD , tetapi ini juga dapat diimplementasikan sebagai penyimpanan internal di perangkat yang berbeda dari penyimpanan internal yang dilindungi dan dapat dipasang sebagai sistem file di komputer. '
LarsH
70

Pertama-tama, kita perlu memahami tentang apa perbedaan antara Penyimpanan Internal, Penyimpanan Eksternal (alias penyimpanan eksternal primer) dan Penyimpanan Eksternal Sekunder?

Penyimpanan Internal: adalah penyimpanan yang tidak dapat diakses oleh pengguna, kecuali melalui aplikasi yang diinstal (atau dengan me-rooting perangkat mereka). Contoh: data / data / app_packageName

Penyimpanan Eksternal Utama: Dalam penyimpanan bersama bawaan yang "dapat diakses oleh pengguna dengan mencolokkan kabel USB dan memasangnya sebagai drive pada komputer host". Contoh: Saat kami mengatakan Nexus 5 32 GB.

Penyimpanan Eksternal Sekunder: Penyimpanan yang dapat dilepas. Contoh: Kartu SD.

getExternalFilesDir (String type)

Ini mengembalikan jalur ke folder file di dalam Android / data / data / your_package / pada penyimpanan eksternal utama. Yang merupakan penyimpanan bawaan.

Environment.getExternalStorageDirectory(type)

Ini akan mengembalikan jalur direktori penyimpanan eksternal sekunder

Vikasdeep Singh
sumber
Terima kasih telah menjelaskan berbagai jenis penyimpanan. Namun, mungkin edit item penyimpanan internal untuk menyebutkan bahwa panggilan metode untuk mendapatkan nilai tersebut adalah getFilesDir (). Ya, saya kira metode itu sebenarnya mengembalikan data / data / app_packageName / files tetapi masih penyimpanan internal.
raddevus
3
@VicJordan Silakan tulis tentang File getExternalStoragePublicDirectory (String type)dan File getFilesDir ()juga
AnV
2
Terima kasih Vic. Environment.getExternalStorageDirectory () keluaran / penyimpanan / ditiru / 0
gimmegimme
Apakah Anda memiliki dokumentasi untuk pernyataan bahwa penyimpanan eksternal primer selalu ada di dalamnya, sedangkan penyimpanan sekunder selalu dapat dilepas? Saya pikir itu adalah masalah independen ... beberapa ponsel tidak memiliki penyimpanan "eksternal" bawaan, dalam hal ini penyimpanan eksternal utama mungkin adalah kartu SD yang dapat dilepas.
LarsH
@ LarsH, sesuai pengetahuan saya saat ini tidak ada telepon di pasar atau dalam waktu dekat yang tidak akan memiliki penyimpanan eksternal utama bawaan. Ada telepon pada saat roti jahe ketika telepon seperti itu ada tetapi tidak sekarang. Bisakah Anda memberi nama "beberapa" ponsel yang tidak memiliki "penyimpanan eksternal primer" bawaan?
Vikasdeep Singh
18

! PEMBARUAN PENTING! untuk siapa pun yang menemukan pertanyaan ini.

Karena ini adalah pertanyaan yang agak lama hanya ingin memberikan beberapa informasi tambahan. Sejak KitKat bahkan aplikasi yang memiliki izin WRITE_EXTERNAL_STORAGE hanya diizinkan untuk menulis ke Android / data / data / your_package / pada penyimpanan eksternal, alias getExternalFilesDir()

Jika Anda akan mencoba menulis kepada getExternalStorageDirectory() + "/somefolder/anotherfolder/"Anda akan mendapatkan SecurityException di sebagian besar perangkat

SGal
sumber
9
Menurut dokumen, aplikasi yang memiliki izin WRITE_EXTERNAL_STORAGE DAPAT menulis ke penyimpanan eksternal paket lain, bukan hanya milik mereka sendiri. Aplikasi yang TIDAK memiliki izin yang hanya dapat menulis ke direktorinya sendiri: developer.android.com/reference/android/content/… "Mulai di KITKAT, tidak ada izin yang diperlukan untuk membaca atau menulis ke jalur yang dikembalikan; itu selalu dapat diakses oleh aplikasi pemanggil ... Untuk mengakses jalur milik paket lain, WRITE_EXTERNAL_STORAGE dan / atau READ_EXTERNAL_STORAGE diperlukan. "
Oded
Di sinilah "pada sebagian besar perangkat" mulai menjadi penting karena dokumen android menggeneralisasi gagasan tersebut, tetapi terkadang produsen memiliki hal-hal seperti InternalStorage (penyimpanan bawaan untuk data aplikasi), ExternalStorage-Primary ( juga penyimpanan bawaan dengan cakupan akses yang lebih besar) dan ExternalStorage-Secondary (ini akan dipasang barang seperti kartu SD). Sekarang Anda dapat menebak jalur mana yang mendapatkan pengembalian External StorageDirectory
SGal
7
Itu tidak mengatasi informasi yang salah dalam jawaban Anda. "Sejak KitKat, bahkan aplikasi yang memiliki izin WRITE_EXTERNAL_STORAGE hanya diizinkan untuk menulis ke Android / data / data / your_package / di penyimpanan eksternal, alias getExternalFilesDir ()". Menurut dokumen, ini salah. Dengan WRITE_EXTERNAL_STORAGE, aplikasi dapat menulis ke semua penyimpanan eksternal.
Oded
1
@Oded, sudahkah Anda menguji ini? Pemahaman saya tentang dokumen, dan pengalaman saya dengan KitKat dan perangkat yang lebih baru, berbeda dari Anda. (Seandainya saya punya waktu untuk membahas semua detail sekarang. Mungkin nanti.) Pengalaman saya adalah bahwa SGal benar. Lalu ada juga Lollipop yang sedikit berbeda.
LarsH
2
Jawaban ini jelas-jelas salah, menurut dokumentasi Android. Lihat developer.android.com/reference/android/… "Mulai API level 19, izin ini tidak diperlukan untuk membaca / menulis file di direktori khusus aplikasi Anda yang dikembalikan oleh getExternalFilesDir (String) dan getExternalCacheDir ()." (Perhatikan bahwa API level 19 = KitKat.) Tidak tahu bagaimana API itu mendapat begitu banyak suara positif.
Ajedi32
7

!! PENTING !!

Environment.getExternalStorageDirectory()tidak digunakan lagi dan Konteks # getExternalFilesDir (String), MediaStore, atau Intent # ACTION_OPEN_DOCUMENT, harus digunakan sebagai gantinya.

Metode ini tidak lagi digunakan di API level 29. Untuk meningkatkan privasi pengguna, akses langsung ke perangkat penyimpanan bersama / eksternal tidak digunakan lagi. Saat aplikasi menargetkan Build.VERSION_CODES.Q, jalur yang dikembalikan dari metode ini tidak lagi dapat diakses secara langsung oleh aplikasi. Aplikasi dapat terus mengakses konten yang disimpan di penyimpanan bersama / eksternal dengan bermigrasi ke alternatif seperti Context # getExternalFilesDir (String), MediaStore, atau Intent # ACTION_OPEN_DOCUMENT.

https://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory ()

Juga mulai dari Android.M pengembang perlu meminta izin pada saat menjalankan.

Lihat lebih detail dalam dokumentasi di sini dan pertanyaan ini

Environment.getExternalStorageDirectory () tidak digunakan lagi di API level 29 java

mayank1513
sumber
jika ada yang mencari link stack overflow dan bukan sesuatu yang disalin dari Google Docs lihat di sini stackoverflow.com/questions/57116335/…
Rowan Berry
1
Mulai Android 11, aplikasi tidak dapat membuat direktori khusus aplikasinya sendiri di penyimpanan eksternal.
Darksymphony