Разница между getExternalFilesDir и getExternalStorageDirectory ()

88

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

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

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

GPGVM
источник

Ответы:

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
это нормально,
подождите
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 () выводит / storage /
emulated
Есть ли у вас документация, подтверждающая, что основное внешнее хранилище всегда является встроенным, а дополнительное - всегда съемным? Я думал, что это независимые проблемы ... некоторые телефоны не имеют встроенного «внешнего» хранилища, и в этом случае основным внешним хранилищем может быть съемная SD-карта.
LarsH 05
@LarsH, насколько мне известно, в настоящее время на рынке и в ближайшем будущем нет телефона, который не имел бы встроенного основного внешнего хранилища. Во времена пряников были телефоны, когда такие телефоны были, но не сейчас. Не могли бы вы назвать «некоторые» телефоны, у которых нет встроенного «основного внешнего хранилища»?
Vikasdeep Singh
17

! ВАЖНОЕ ОБНОВЛЕНИЕ! для тех, кто сталкивается с этим вопросом.

Поскольку это несколько старый вопрос, я просто хотел предоставить дополнительную информацию. Так как KitKat даже приложение , которые имеют WRITE_EXTERNAL_STORAGE разрешения будет разрешено только для записи на Android / данные / данные / your_package / на внешнем накопителе, иначе getExternalFilesDir()

Если вы попытаетесь написать, getExternalStorageDirectory() + "/somefolder/anotherfolder/"вы получите SecurityException на большинстве устройств.

SGal
источник
9
Согласно документам, приложения с разрешением WRITE_EXTERNAL_STORAGE МОГУТ записывать во внешнее хранилище других пакетов, а не только в свое собственное. Это приложения, у которых нет разрешения, которое может записывать только в свой собственный каталог: developer.android.com/reference/android/content/… "Начиная с KITKAT, никаких разрешений не требуется для чтения или записи в возвращаемый путь; это всегда доступны для вызывающего приложения ... Для доступа к путям, принадлежащим другим пакетам, требуются WRITE_EXTERNAL_STORAGE и / или READ_EXTERNAL_STORAGE. "
Одед
Именно здесь «на большинстве устройств» начинает иметь значение, поскольку документация по Android обобщает эту идею, но производители иногда имеют такие вещи, как InternalStorage (встроенное хранилище для данных приложения), ExternalStorage-Primary ( также встроенное хранилище с большей областью доступа) и ExternalStorage-Secondary (это будет монтироваться как SD-карты). Теперь вы можете угадать, по какому пути возвращается External StorageDirectory
SGal,
7
Это не относится к неверной информации в вашем ответе. «Поскольку KitKat, даже приложениям, имеющим разрешение WRITE_EXTERNAL_STORAGE, разрешена запись только в Android / data / data / your_package / на внешнем хранилище, также известном как getExternalFilesDir ()». Согласно документам, это неправильно. С WRITE_EXTERNAL_STORAGE приложения могут писать во все внешние хранилища.
Oded
1
@Oded, ты это тестировал? Мое понимание документации и мой опыт работы с KitKat и более поздними устройствами отличается от вашего. (Хотелось бы, чтобы у меня было время обсудить все детали сейчас. Может быть, позже.) Мой опыт показывает, что SGal прав. Еще есть Lollipop, который немного отличается.
LarsH 05
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 () устарела на уровне API 29 java

майанк1513
источник
если кто-то ищет ссылку на переполнение стека, а не что-то скопированное из документов Google, посмотрите здесь stackoverflow.com/questions/57116335/…
Роуэн Берри
1
Начиная с Android 11, приложения не могут создавать свои собственные каталоги для конкретных приложений во внешнем хранилище.
Darksymphony