Різниця між getExternalFilesDir і getExternalStorageDirectory ()


89

Я розумію, що ExternalFiles слід використовувати на API 8 та новіших версій, а getExternalStorageDirectory - на 7 і нижче. Однак я трохи плутаюсь між використанням. Наприклад, я хотів перевірити, що папка існує, і раніше ви використовували щось на зразок:

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

Однак кожен приклад, який я бачу, говорить про використання getExternalFilesDir (null), File.ext. Оскільки я перевищую API 8, я хочу використовувати цей метод, але як мені просто перевірити наявність папки? Я перевірю наявність файлів в інший момент, але наразі просто хочу побачити, чи існують папки ??

Відповіді:


132
getExternalFilesDir()

Він повертає шлях до папки файлів в Android / data / data / your_package / на вашій SD-карті. Він використовується для зберігання будь-яких необхідних файлів для вашої програми (наприклад, зображень, завантажених з Інтернету або кеш-файлів). Після видалення програми всі дані, що зберігаються в цій папці, також втрачаються.

getExternalStorageDirectory()

Він повертає кореневий шлях до вашої SD-карти (наприклад, mnt / sdcard / ). Якщо ви збережете дані за цим шляхом та видалите програму, ці дані не будуть втрачені.


4
Google Android хоче, щоб ви використовували все, що вони надають у рамках. Тож це залежить від вашого вибору та вимог до дизайну. Якщо ви не хочете, щоб файли залишалися вліво під час видалення програми, вам рекомендується використовувати getExternalFilesDir () або getExternalCacheDir ()
waqaslam,

5
Це тому, що в API 8 вони ввели розширені функції сканера мультимедіа, які дозволяють сканувати дані з папок, таких як музика, картинки, мелодії дзвінка тощо. Ці каталоги автоматично створюються лише за умови використання getExternalFilesDir () . Тепер, оскільки ця функція була недоступна в API 7, саме тому вони рекомендували використовувати getExternalStorageDirectory () . Просто ...
waqaslam

2
його добре, дати йому деякий час, скоро буде еврика момент :)
waqaslam

3
Важливо знати , що getExternalStorageDirectory()зовсім не обов'язково - може бути , навіть не звичайно - повернути «шлях до вашої SD - карти.» Натомість він повертає "основний каталог зовнішнього сховища". У документах ( developer.android.com/reference/android/os/… ) сказано:
LarsH

2
'Примітка: тут вас не бентежить слово "зовнішній". Цей каталог можна вважати мультимедійним / спільним сховищем. Це файлова система, яка вміщує відносно великий обсяг даних і спільно використовується між усіма програмами (не застосовує дозволів). Традиційно це SD-карта , але вона також може бути реалізована як вбудована пам'ять на пристрої, який відрізняється від захищеного внутрішнього сховища і може бути встановлений як файлова система на комп'ютері. '
LarsH

69

Перш за все, нам слід зрозуміти, в чому різниця між внутрішньою, зовнішньою пам’яттю (вона ж первинна зовнішня пам’ять) і вторинною зовнішньою пам’яттю?

Внутрішня пам’ять: це пам’ять, до якої користувач не має доступу, за винятком встановлених програм (або шляхом вкорінення їх пристрою). Приклад: data / data / app_packageName

Первинне зовнішнє сховище: у вбудованому спільному сховищі, яке "доступне користувачеві, підключивши кабель USB та встановивши його як привід на головному комп'ютері". Приклад: Коли ми говоримо про Nexus 5, 32 ГБ.

Вторинне зовнішнє сховище: знімне сховище. Приклад: SD-карта.

getExternalFilesDir (String type)

Він повертає шлях до папки файлів в Android / data / data / your_package / на первинному зовнішньому сховищі. Що є вбудованим сховищем.

Environment.getExternalStorageDirectory(type)

Він поверне шлях до вторинного каталогу зовнішнього сховища


Дякуємо за пояснення різних типів сховища. Однак, можливо, відредагуйте елемент внутрішнього сховища, щоб згадати, що виклик методу для отримання цього значення - getFilesDir (). Ну, я думаю, цей метод фактично повертає data / data / app_packageName / files, але він все ще є внутрішньою пам’яттю.
raddevus

3
@VicJordan Будь ласка, напишіть про це, File getExternalStoragePublicDirectory (String type)а File getFilesDir ()також
AnV

2
Дякую Вік. Environment.getExternalStorageDirectory ()
outputs

Чи є у вас документація для твердження, що первинна зовнішня пам’ять завжди вбудована, тоді як вторинна завжди є знімною? Я думав, що це незалежні проблеми ... деякі телефони не мають вбудованого "зовнішнього" сховища, і в цьому випадку основним зовнішнім сховищем може бути знімна SD-карта.
LarsH

@LarsH, наскільки мені відомо, на сьогоднішній день на ринку немає або найближчим часом телефон, який би не мав вбудованого первинного зовнішнього сховища. Існували телефони за часів пряників, коли такі телефони існували, але не зараз. Не могли б ви назвати "деякі" телефони, які не мають вбудованого "основного зовнішнього сховища"?
Вікасдіп Сінгх

17

! ВАЖЛИВЕ ОНОВЛЕННЯ! для того, хто стикається з цим питанням.

Оскільки це дещо застаріле питання, я просто хотів надати додаткову інформацію. Оскільки KitKat навіть програмам, які мають дозвіл WRITE_EXTERNAL_STORAGE , дозволяється писати лише на Android / data / data / your_package / на зовнішньому сховищі, він же getExternalFilesDir()

Якщо ви спробуєте написати, getExternalStorageDirectory() + "/somefolder/anotherfolder/"ви отримаєте виняток SecurityException на більшості пристроїв


9
Згідно з документами, програми, які мають дозвіл WRITE_EXTERNAL_STORAGE, МОЖУТЬ писати на зовнішню пам’ять інших пакунків, а не лише їх власну. Це додатки, які НЕ мають дозволу, і можуть писати лише у власний каталог: developer.android.com/reference/android/content/… "Починаючи з KITKAT, не потрібні дозволи на читання або запис у повернутий шлях; це завжди доступний для програми, що викликає ... Для доступу до шляхів, що належать до інших пакетів, потрібні WRITE_EXTERNAL_STORAGE та / або READ_EXTERNAL_STORAGE. "
Оді

Тут починає мати значення "на більшості пристроїв", оскільки документи Android узагальнюють ідею, але виробники іноді мають такі речі, як InternalStorage (вбудоване сховище для даних додатків), ExternalStorage-Primary ( також вбудоване сховище з більшим обсягом доступу) та ExternalStorage-Secondary (це буде змонтований матеріал, такий як SD-карти). Тепер ви можете зробити припущення , який шлях отримати зовнішні повернення StorageDirectory
SGal

7
Це не стосується неправильної інформації у вашій відповіді. "Оскільки KitKat навіть програмам, які мають дозвіл WRITE_EXTERNAL_STORAGE, дозволено писати лише на Android / data / data / your_package / на зовнішньому сховищі, інакше getExternalFilesDir ()". Згідно з документами, це неправильно. Завдяки WRITE_EXTERNAL_STORAGE програми можуть писати на всю зовнішню пам’ять.
Одіс

1
@Oded, ви тестували це? Моє розуміння документів та досвід роботи з KitKat та пізнішими пристроями відрізняється від вашого. (Хотілося б, щоб я зараз встиг вибити всі деталі. Може, пізніше.) Мій досвід полягає в тому, що SGal має рацію. Тоді є також льодяник, який трохи відрізняється.
LarsH

2
Відповідно до документації Android, ця відповідь є відверто неправдивою. Див. Developer.android.com/reference/android/… "Починаючи з API рівня 19, цей дозвіл не потрібен для читання / запису файлів у конкретних додатках, що повертаються getExternalFilesDir (String) і getExternalCacheDir ()." (Зверніть увагу, що рівень API 19 = KitKat.) Не уявляю, як він отримав стільки голосів.
Ajedi32

6

!! ВАЖЛИВО !!

Environment.getExternalStorageDirectory()є застарілим і контекст # getExternalFilesDir (String), MediaStore або Намір # ACTION_OPEN_DOCUMENT, слід використовувати замість цього.

Цей метод було застарілим на рівні API 29. Для поліпшення конфіденційності користувачів прямий доступ до спільних / зовнішніх пристроїв зберігання даних не підтримується. Коли програма націлена на Build.VERSION_CODES.Q, шлях, повернутий із цього методу, більше не є безпосередньо доступним для програм. Програми можуть продовжувати отримувати доступ до вмісту, що зберігається у спільному / зовнішньому сховищі, переходячи до таких альтернатив, як Context # getExternalFilesDir (String), MediaStore або Intent # ACTION_OPEN_DOCUMENT.

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

Також починаючи з Android.M розробникам потрібно запитувати дозволи під час роботи.

Детальніше див. У документації тут та це питання

Environment.getExternalStorageDirectory () застаріло в Java рівня 29 Java


якщо хтось шукає посилання на переповнення стека, а не щось, скопійоване з документів Google, дивіться тут stackoverflow.com/questions/57116335/…
Роуан Беррі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.