Różnica między getExternalFilesDir i getExternalStorageDirectory ()

88

Rozumiem, że ExternalFiles ma być używany w API 8 i nowszych, a getExternalStorageDirectory jest przeznaczony dla wersji 7 i starszych. Jednak jestem trochę zdezorientowany między użyciem. Na przykład chciałem sprawdzić, czy istnieje folder, a wcześniej używałbyś czegoś takiego:

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

Jednak każdy przykład, który widzę, mówi, aby użyć getExternalFilesDir (null), File.ext. Ponieważ jestem powyżej API 8, chcę użyć tej metody, ale jak po prostu sprawdzić, czy istnieje folder? Sprawdzę istnienie plików w innym momencie, ale na razie chcę tylko sprawdzić, czy foldery istnieją?

GPGVM
źródło

Odpowiedzi:

132
getExternalFilesDir()

Zwraca ścieżkę do folderu plików w systemie Android / data / data / your_package / na karcie SD. Służy do przechowywania wszelkich wymaganych plików dla Twojej aplikacji (np. Obrazów pobranych z Internetu lub plików pamięci podręcznej). Po odinstalowaniu aplikacji wszelkie dane przechowywane w tym folderze również znikają.

getExternalStorageDirectory()

Zwraca ścieżkę główną do karty SD (np. Mnt / sdcard / ). Jeśli zapiszesz dane na tej ścieżce i odinstalujesz aplikację, te dane nie zostaną utracone.

waqaslam
źródło
4
Google Android chce, abyś korzystał z wszystkiego, co zapewnia w ramach. Więc to zależy od twojego wyboru i wymagań projektowych. Jeśli nie chcesz, aby pliki pozostały pozostawione po odinstalowaniu aplikacji, zachęcamy do korzystania z getExternalFilesDir () lub getExternalCacheDir ()
waqaslam
5
To dlatego, że w API 8 wprowadzili zaawansowane funkcje skanera multimediów, które umożliwiają skanowanie danych z folderów, takich jak muzyka, obrazy, dzwonki itp. Te katalogi są tworzone automatycznie tylko wtedy, gdy używasz getExternalFilesDir () . Ponieważ ta funkcja nie była dostępna w API 7, dlatego zalecono użycie metody getExternalStorageDirectory () . Proste ...
waqaslam
2
jest ok, daj mu trochę czasu, wkrótce będzie moment eureka :)
waqaslam
3
Ważne jest, aby wiedzieć, że getExternalStorageDirectory()nie niekoniecznie - może nawet nie zwykle - „ścieżkę do karty SD” powrót Zamiast tego zwraca „podstawowy katalog pamięci zewnętrznej”. Dokumenty ( developer.android.com/reference/android/os/… ) mówią:
LarsH
2
Uwaga: nie daj się zmylić słowem „zewnętrzny”. Ten katalog można lepiej traktować jako nośnik / pamięć współdzieloną. Jest to system plików, który może pomieścić stosunkowo dużą ilość danych i jest współdzielony przez wszystkie aplikacje (nie wymusza uprawnień). Tradycyjnie jest to karta SD , ale można ją również zaimplementować jako pamięć wbudowaną w urządzeniu, które różni się od chronionej pamięci wewnętrznej i można ją zamontować jako system plików na komputerze ”.
LarsH
69

Przede wszystkim musimy zrozumieć, jaka jest różnica między pamięcią wewnętrzną, pamięcią zewnętrzną (czyli podstawową pamięcią zewnętrzną) i dodatkową pamięcią zewnętrzną?

Pamięć wewnętrzna: to pamięć niedostępna dla użytkownika, z wyjątkiem zainstalowanych aplikacji (lub przez zrootowanie urządzenia). Przykład: data / data / app_packageName

Podstawowa pamięć zewnętrzna: wbudowana pamięć współdzielona, ​​„dostępna dla użytkownika po podłączeniu kabla USB i zamontowaniu go jako dysku na komputerze hosta”. Przykład: kiedy mówimy o Nexusie 5 32 GB.

Dodatkowa pamięć zewnętrzna: pamięć wymienna. Przykład: karta SD.

getExternalFilesDir (String type)

Zwraca ścieżkę do folderu plików w systemie Android / data / data / your_package / na podstawowej zewnętrznej pamięci masowej. Który jest wbudowanym magazynem.

Environment.getExternalStorageDirectory(type)

Zwróci ścieżkę do dodatkowego katalogu zewnętrznego magazynu

Vikasdeep Singh
źródło
Dziękuję za wyjaśnienie różnych rodzajów przechowywania. Jednak może edytuj element pamięci wewnętrznej, aby wspomnieć, że wywołanie metody w celu uzyskania tej wartości to getFilesDir (). Cóż, myślę, że ta metoda w rzeczywistości zwraca dane / dane / nazwa_pakietu_aplikacji / pliki, ale nadal jest to pamięć wewnętrzna.
raddevus
3
@VicJordan Proszę pisać o File getExternalStoragePublicDirectory (String type)i File getFilesDir ()również
AnV
2
Dzięki Vic. Environment.getExternalStorageDirectory () output / storage /
emulated
Czy masz dokumentację stwierdzającą, że podstawowa pamięć zewnętrzna jest zawsze wbudowana, a pomocnicza jest zawsze wymienna? Myślałem, że to niezależne problemy… niektóre telefony nie mają wbudowanej pamięci „zewnętrznej”, w takim przypadku główną pamięcią zewnętrzną może być wymienna karta SD.
LarsH,
@LarsH, zgodnie z moją wiedzą obecnie nie ma na rynku ani w najbliższej przyszłości telefonu, który nie miałby wbudowanej podstawowej pamięci zewnętrznej. Były telefony w czasach piernika, kiedy takie telefony istniały, ale nie teraz. Czy mógłbyś wymienić „niektóre” telefony, które nie mają wbudowanej „podstawowej pamięci zewnętrznej”?
Vikasdeep Singh
17

! WAŻNA AKTUALIZACJA! dla każdego, kto zetknie się z tym pytaniem.

Ponieważ jest to dość stare pytanie, chciałem tylko podać dodatkowe informacje. Od KitKat nawet aplikacje, które mają uprawnienie WRITE_EXTERNAL_STORAGE, mogą zapisywać tylko do Androida / data / data / your_package / na zewnętrznej pamięci masowej, czyli getExternalFilesDir()

Jeśli spróbujesz napisać do getExternalStorageDirectory() + "/somefolder/anotherfolder/"ciebie, otrzymasz SecurityException na większości urządzeń

SGal
źródło
9
Zgodnie z dokumentacją aplikacje, które mają uprawnienie WRITE_EXTERNAL_STORAGE, mogą zapisywać w pamięci zewnętrznej innych pakietów, a nie tylko we własnej. To aplikacje, które NIE mają uprawnień, które mogą zapisywać tylko w swoim własnym katalogu: developer.android.com/reference/android/content/ ... „Począwszy od KITKAT, nie są wymagane żadne uprawnienia do odczytu lub zapisu w zwróconej ścieżce; jest to zawsze dostępne dla aplikacji wywołującej ... Aby uzyskać dostęp do ścieżek należących do innych pakietów, wymagane są WRITE_EXTERNAL_STORAGE i / lub READ_EXTERNAL_STORAGE. "
Oded
W tym miejscu „na większości urządzeń” zaczyna mieć znaczenie, ponieważ dokumenty systemu Android uogólniają ten pomysł, ale producenci czasami mają takie rzeczy, jak InternalStorage (wbudowana pamięć na dane aplikacji), ExternalStorage-Primary ( również wbudowana pamięć z większym zakresem dostępu) i ExternalStorage-Secondary (będzie to montowane rzeczy, takie jak karty SD). Teraz możesz zgadnąć, która ścieżka
spowoduje
7
To nie dotyczy nieprawidłowych informacji w Twojej odpowiedzi. „Od KitKat nawet aplikacje, które mają uprawnienie WRITE_EXTERNAL_STORAGE, mogą zapisywać tylko w systemie Android / data / data / your_package / na zewnętrznej pamięci masowej, czyli getExternalFilesDir ()”. Według dokumentacji, to jest złe. Dzięki WRITE_EXTERNAL_STORAGE aplikacje mogą zapisywać w całej pamięci zewnętrznej.
Oded
1
@Oded, czy przetestowałeś to? Moje rozumienie dokumentacji i moje doświadczenie z KitKatem i nowszymi urządzeniami różni się od Twojego. (Żałuję, że nie mam czasu, aby teraz zgasić wszystkie szczegóły. Może później.) Z mojego doświadczenia wynika, że ​​SGal ma rację. Jest też Lollipop, który jest trochę inny.
LarsH,
2
Ta odpowiedź jest rażąco fałszywa, zgodnie z dokumentacją Androida. Zobacz developer.android.com/reference/android/… "Począwszy od 19 poziomu API, to uprawnienie nie jest wymagane do odczytu / zapisu plików w katalogach specyficznych dla aplikacji zwracanych przez getExternalFilesDir (String) i getExternalCacheDir ()." (Zwróć uwagę, że poziom API 19 = KitKat.) Nie mam pojęcia, skąd wzięło się tak wiele pozytywnych głosów.
Ajedi32
6

!! WAŻNE !!

Environment.getExternalStorageDirectory() jest przestarzałe i zamiast tego należy użyć Context # getExternalFilesDir (String), MediaStore lub Intent # ACTION_OPEN_DOCUMENT.

Ta metoda została wycofana na poziomie interfejsu API 29. Aby zwiększyć prywatność użytkowników, bezpośredni dostęp do udostępnionych / zewnętrznych urządzeń pamięci masowej jest przestarzały. Gdy aplikacja jest przeznaczona dla Build.VERSION_CODES.Q, ścieżka zwrócona przez tę metodę nie jest już bezpośrednio dostępna dla aplikacji. Aplikacje mogą nadal uzyskiwać dostęp do treści przechowywanych w pamięci współdzielonej / zewnętrznej, migrując do alternatyw, takich jak Context # getExternalFilesDir (String), MediaStore lub Intent # ACTION_OPEN_DOCUMENT.

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

Również zaczynając od Androida.M programiści muszą prosić o uprawnienia w czasie wykonywania.

Zobacz więcej szczegółów w dokumentacji tutaj i to pytanie

Environment.getExternalStorageDirectory () została uznana za przestarzałą w języku API 29 poziomu java

mayank1513
źródło
jeśli ktoś szuka linku do przepełnienia stosu, a nie czegoś wklejonego z dokumentów google, zajrzyj tutaj stackoverflow.com/questions/57116335/…
Rowan Berry
1
Począwszy od systemu Android 11, aplikacje nie mogą tworzyć własnego katalogu specyficznego dla aplikacji w pamięci zewnętrznej.
Darksymphony