Unterschied zwischen getExternalFilesDir und getExternalStorageDirectory ()

88

Ich verstehe, dass ExternalFiles für API 8 und höher verwendet werden soll und getExternalStorageDirectory für 7 und höher. Ich bin jedoch ein wenig verwirrt zwischen der Verwendung. Zum Beispiel wollte ich überprüfen, ob ein Ordner existiert und vorher würden Sie etwas verwenden wie:

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

In jedem Beispiel heißt es jedoch, getExternalFilesDir (null), File.ext, zu verwenden. Da ich über API 8 bin, möchte ich diese Methode verwenden, aber wie suche ich einfach nach einem Ordner? Ich werde an einer anderen Stelle nach einer Datei suchen, möchte aber vorerst nur sehen, ob die Ordner vorhanden sind.

GPGVM
quelle

Antworten:

128
getExternalFilesDir()

Es gibt den Pfad zu Dateien Ordner im Android / data / data / your_package / auf der SD - Karte. Es wird verwendet, um alle erforderlichen Dateien für Ihre App zu speichern (z. B. Bilder, die aus Web- oder Cache-Dateien heruntergeladen wurden). Sobald die App deinstalliert ist, werden auch alle in diesem Ordner gespeicherten Daten gelöscht.

getExternalStorageDirectory()

Es gibt den Root-Pfad zu Ihrer SD-Karte zurück (z. B. mnt / sdcard / ). Wenn Sie Daten auf diesem Pfad speichern und die App deinstallieren, gehen diese Daten nicht verloren.

Waqaslam
quelle
1
Wollen Sie damit sagen, dass Google Android-Leute möchten, dass Sie nur getExternalFilesDir () API 8 und höher verwenden, wenn Sie konform sind, werden Ihre Dateien bei der Deinstallation gelöscht? Versteh mich nicht falsch, ich möchte dieses Verhalten, da ich nicht möchte, dass Dateien übrig bleiben, wenn jemand deinstalliert. Das andere Element, bei dem ich mir nicht sicher bin, aber jetzt experimentiere, ist genau, wie es zurückgegeben wird, wenn ein Ordner vorhanden ist. Für diese Zeile wird beispielsweise Folgendes zurückgegeben: File (getExternalFilesDir (null), "/ ParentFldr / ChildFldr");
GPGVM
4
Google Android möchte, dass Sie alles verwenden, was im Rahmen bereitgestellt wird. Es liegt also an Ihrer Wahl und Ihren Designanforderungen. Wenn Sie nicht möchten, dass die Dateien bei der Deinstallation der App übrig bleiben, sollten Sie getExternalFilesDir () oder getExternalCacheDir () verwenden
waqaslam
5
Dies liegt daran, dass in API 8 erweiterte Medienscannerfunktionen eingeführt wurden, mit denen Daten aus Ordnern wie Musik, Bildern, Klingeltönen usw. gescannt werden können. Diese Verzeichnisse werden automatisch nur erstellt, wenn Sie getExternalFilesDir () verwenden . Da diese Funktion in API 7 nicht verfügbar war, wurde die Verwendung von getExternalStorageDirectory () empfohlen . Einfach ...
Waqaslam
2
Es ist in Ordnung , gib ihm etwas Zeit, bald wird es einen Eureka- Moment geben :)
Waqaslam
2
Es ist wichtig zu wissen , dass getExternalStorageDirectory()sie nicht unbedingt - vielleicht auch nicht in die Regel - „Pfad zu Ihrer SD-Karte“ Rückkehr des Stattdessen wird das "primäre externe Speicherverzeichnis" zurückgegeben. Die Dokumente ( developer.android.com/reference/android/os/… ) sagen:
LarsH
64

Zunächst müssen wir verstehen, was der Unterschied zwischen internem Speicher, externem Speicher (auch als primärer externer Speicher bezeichnet) und sekundärem externem Speicher ist.

Interner Speicher: ist Speicher, auf den der Benutzer nur über installierte Apps (oder durch Rooten seines Geräts) zugreifen kann. Beispiel: data / data / app_packageName

Primärer externer Speicher: Eingebauter gemeinsamer Speicher, auf den der Benutzer zugreifen kann, indem er ein USB-Kabel einsteckt und es als Laufwerk auf einem Host-Computer anbringt. Beispiel: Wenn wir Nexus 5 32 GB sagen.

Sekundärer externer Speicher: Wechselspeicher. Beispiel: SD-Karte.

getExternalFilesDir (String type)

Es gibt den Pfad zum Dateiordner in Android / data / data / your_package / auf dem primären externen Speicher zurück. Welches ist eingebauter Speicher.

getExternalStorageDirectory ()

Es wird der Pfad des sekundären externen Speicherverzeichnisses zurückgegeben

Vikasdeep Singh
quelle
Vielen Dank für die Erläuterung der verschiedenen Arten der Speicherung. Bearbeiten Sie jedoch möglicherweise das interne Speicherelement , um zu erwähnen, dass der Methodenaufruf zum Abrufen dieses Werts getFilesDir () lautet. Nun, ich denke, diese Methode gibt tatsächlich data / data / app_packageName / files zurück, aber es ist immer noch interner Speicher.
Raddevus
3
@VicJordan Bitte schreiben Sie über File getExternalStoragePublicDirectory (String type)und File getFilesDir ()auch
AnV
1
Danke Vic. Environment.getExternalStorageDirectory () gibt / storage /
emulated
Haben Sie eine Dokumentation für die Aussage, dass der primäre externe Speicher immer integriert ist, während der sekundäre immer entfernbar ist? Ich dachte, das wären unabhängige Probleme ... einige Telefone haben keinen eingebauten "externen" Speicher. In diesem Fall könnte der primäre externe Speicher die austauschbare SD-Karte sein.
LarsH
@LarsH, meines Wissens nach gibt es derzeit kein Telefon auf dem Markt oder in naher Zukunft, das keinen eingebauten primären externen Speicher haben wird. Es gab Telefone zur Zeit des Lebkuchens, als solche Telefone existierten, aber nicht jetzt. Könnten Sie bitte "einige" Telefone nennen, die keinen eingebauten "primären externen Speicher" haben?
Vikasdeep Singh
17

! WICHTIGES UPDATE! für jeden, der auf diese Frage stößt.

Da dies eine etwas alte Frage ist, wollte ich nur einige zusätzliche Informationen liefern. Da Apps KitKat auch die haben WRITE_EXTERNAL_STORAGE Erlaubnis sind nur erlaubt , zu schreiben , um Android / data / data / your_package / auf externen Speicher, aka getExternalFilesDir()

Wenn Sie versuchen, zu schreiben, erhalten getExternalStorageDirectory() + "/somefolder/anotherfolder/"Sie auf den meisten Geräten eine SecurityException

SGal
quelle
9
Laut den Dokumenten können Apps mit der Berechtigung WRITE_EXTERNAL_STORAGE in den externen Speicher anderer Pakete schreiben, nicht nur in ihren eigenen. Es sind Apps, die NICHT über die Berechtigung verfügen, die nur in ihr eigenes Verzeichnis schreiben können: developer.android.com/reference/android/content/… "Ab KITKAT sind keine Berechtigungen zum Lesen oder Schreiben in den zurückgegebenen Pfad erforderlich. Dies ist immer der Fall Zugriff auf die aufrufende App ... Um auf Pfade zuzugreifen, die zu anderen Paketen gehören, sind WRITE_EXTERNAL_STORAGE und / oder READ_EXTERNAL_STORAGE erforderlich. "
Oded
Hier beginnt "auf den meisten Geräten" eine Rolle zu spielen, da Android-Dokumente die Idee verallgemeinern, aber Hersteller haben manchmal Dinge wie InternalStorage (integrierter Speicher für App-Daten), ExternalStorage-Primary ( auch integrierter Speicher mit einem größeren Zugriffsbereich). und ExternalStorage-Secondary (dies wären gemountete Sachen wie SD-Karten). Jetzt können Sie erraten, welcher Pfad External StorageDirectory zurückgibt
SGal
7
Damit werden die falschen Informationen in Ihrer Antwort nicht behoben. "Da KitKat auch Apps mit der Berechtigung WRITE_EXTERNAL_STORAGE nur auf Android / data / data / your_package / im externen Speicher schreiben dürfen, auch bekannt als getExternalFilesDir ()". Laut den Dokumenten ist dies falsch. Mit WRITE_EXTERNAL_STORAGE können Apps in den gesamten externen Speicher schreiben.
Oded
1
@Oded, hast du das getestet? Mein Verständnis der Dokumente und meine Erfahrung mit KitKat und späteren Geräten unterscheidet sich von Ihrem. (Ich wünschte, ich hätte jetzt Zeit, alle Details herauszufinden. Vielleicht später.) Meine Erfahrung ist, dass SGal Recht hat. Dann gibt es noch Lollipop, der etwas anders ist.
LarsH
2
Diese Antwort ist laut Android-Dokumentation offensichtlich falsch. Siehe developer.android.com/reference/android/… "Ab API-Ebene 19 ist diese Berechtigung nicht erforderlich, um Dateien in Ihren anwendungsspezifischen Verzeichnissen zu lesen / schreiben, die von getExternalFilesDir (String) und getExternalCacheDir () zurückgegeben werden." (Beachten Sie, dass API-Level 19 = KitKat.) Keine Ahnung, wie es zu so vielen Upvotes gekommen ist.
Ajedi32
6

!! WICHTIG !!

Environment.getExternalStorageDirectory()ist veraltet und stattdessen sollte Context # getExternalFilesDir (String), MediaStore oder Intent # ACTION_OPEN_DOCUMENT verwendet werden.

Diese Methode wurde in API-Stufe 29 nicht mehr unterstützt. Um die Privatsphäre der Benutzer zu verbessern, ist der direkte Zugriff auf gemeinsam genutzte / externe Speichergeräte veraltet. Wenn eine App auf Build.VERSION_CODES.Q abzielt, ist der von dieser Methode zurückgegebene Pfad für Apps nicht mehr direkt zugänglich. Apps können weiterhin auf Inhalte zugreifen, die im gemeinsam genutzten / externen Speicher gespeichert sind, indem sie zu Alternativen wie Context # getExternalFilesDir (String), MediaStore oder Intent # ACTION_OPEN_DOCUMENT migrieren.

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

Ebenfalls ab Android.M müssen Entwickler zur Laufzeit nach Berechtigungen fragen.

Weitere Details finden Sie in der Dokumentation hier und in dieser Frage

Environment.getExternalStorageDirectory () ist in Java der API-Ebene 29 veraltet

mayank1513
quelle
Wenn jemand nach einem Stapelüberlauf-Link sucht und nicht nach einer Kopie, die aus Google Docs eingefügt wurde
Rowan Berry