Android
Speichern von Dateien im internen und externen Speicher
Suche…
Syntax
- FileOutputStream openFileInput (Name der Zeichenfolge)
- FileOutputStream openFileOutput (Stringname, int-Modus)
- Datei (Dateiname, Stringname)
- Datei (String-Pfad)
- Datei getExternalStoragePublicDirectory (String-Typ)
- Datei getExternalFilesDir (String-Typ)
Parameter
Parameter | Einzelheiten |
---|---|
Name | Der Name der zu öffnenden Datei. HINWEIS: Kann keine Pfadtrennzeichen enthalten |
Modus | Betriebsart. Verwenden Sie MODE_PRIVATE für die Standardoperation und MODE_APPEND , um eine vorhandene Datei MODE_APPEND . Andere Modi umfassen MODE_WORLD_READABLE und MODE_WORLD_WRITEABLE , die beide in API 17 nicht mehr unterstützt werden. |
dir | Verzeichnis der Datei, in der eine neue Datei erstellt werden soll |
Pfad | Pfad zum Angeben des Speicherorts der neuen Datei |
Art | Typ des abzurufenden Dateiverzeichnisses. Kann null oder eine der folgenden sein: DIRECTORY_MUSIC , DIRECTORY_PODCASTS , DIRECTORY_RINGTONES , DIRECTORY_ALARMS , DIRECTORY_NOTIFICATIONS , DIRECTORY_PICTURES oder DIRECTORY_MOVIES |
Internen Speicher verwenden
Standardmäßig sind alle Dateien, die Sie im internen Speicher speichern, für Ihre Anwendung privat. Auf sie kann weder von anderen Anwendungen noch vom Benutzer unter normalen Umständen zugegriffen werden. Diese Dateien werden gelöscht, wenn der Benutzer die Anwendung deinstalliert .
So schreiben Sie Text in eine Datei
String fileName= "helloworld";
String textToWrite = "Hello, World!";
FileOutputStream fileOutputStream;
try {
fileOutputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
fileOutputStream.write(textToWrite.getBytes());
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
So hängen Sie Text an eine vorhandene Datei an
Verwenden Sie Context.MODE_APPEND
für den openFileOutput
von openFileOutput
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
Externen Speicher verwenden
"Externer" Speicher ist eine andere Art von Speicher, mit dem Dateien auf dem Gerät des Benutzers gespeichert werden können. Es gibt einige wesentliche Unterschiede zum "internen" Speicher, nämlich:
- Es ist nicht immer verfügbar. Bei einem Wechselmedium (SD-Karte) kann der Benutzer den Speicher einfach entfernen.
- Es ist nicht privat. Der Benutzer (und andere Anwendungen) haben Zugriff auf diese Dateien.
- Wenn der Benutzer die App deinstalliert, werden die Dateien, die Sie in dem mit
getExternalFilesDir()
abgerufenen VerzeichnisgetExternalFilesDir()
, entfernt.
Um externen Speicher verwenden zu können, müssen wir zunächst die richtigen Berechtigungen erwerben. Sie müssen verwenden:
-
android.permission.WRITE_EXTERNAL_STORAGE
zum Lesen und Schreiben -
android.permission.READ_EXTERNAL_STORAGE
zum Lesen
Um diese Berechtigungen zu erteilen, müssen Sie sie in Ihrer AndroidManifest.xml
als solche identifizieren
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
HINWEIS: Da es sich um gefährliche Berechtigungen handelt, wenn Sie API-Level 23 oder höher verwenden, müssen Sie die Berechtigungen zur Laufzeit anfordern.
Bevor Sie versuchen, aus einem externen Speicher zu schreiben oder zu lesen, sollten Sie immer überprüfen, ob das Speichermedium verfügbar ist.
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Available to read and write
}
if (state.equals(Environment.MEDIA_MOUNTED) ||
state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
// Available to at least read
}
Beim Schreiben von Dateien auf den externen Speicher sollten Sie entscheiden, ob die Datei als öffentlich oder privat erkannt werden soll. Während diese beiden Dateitypen für den Benutzer und andere Anwendungen auf dem Gerät weiterhin verfügbar sind, besteht ein wesentlicher Unterschied zwischen ihnen.
Öffentliche Dateien sollten auf dem Gerät verbleiben, wenn der Benutzer die App deinstalliert. Ein Beispiel für eine Datei, die als öffentlich gespeichert werden soll, sind Fotos, die von Ihrer Anwendung aufgenommen werden.
Private Dateien sollten alle entfernt werden, wenn der Benutzer die App deinstalliert. Diese Dateitypen wären app-spezifisch und für den Benutzer oder andere Anwendungen nicht von Nutzen. Ex. temporäre Dateien, die von Ihrer Anwendung heruntergeladen / verwendet werden.
So erhalten Sie Zugriff auf das Verzeichnis Documents
für öffentliche und private Dateien.
Öffentlichkeit
// Access your app's directory in the device's Public documents directory
File docs = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), "YourAppDirectory");
// Make the directory if it does not yet exist
myDocs.mkdirs();
Privatgelände
// Access your app's Private documents directory
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),
"YourAppDirectory");
// Make the directory if it does not yet exist
myDocs.mkdirs();
Android: Interner und externer Speicher - Erläuterung der Terminologie
Android-Entwickler (hauptsächlich Anfänger) wurden hinsichtlich der Terminologie für interne und externe Speicherung verwirrt. Es gibt viele Fragen zu Stackoverflow, die das gleiche betreffen. Dies ist hauptsächlich darauf zurückzuführen, dass sich die Terminologie gemäß der offiziellen Dokumentation von Google / Android von der eines normalen Android-Betriebssystems unterscheidet. Daher dachte ich, die Dokumentation würde helfen.
Was wir denken - Benutzerterminologie (UT)
Interner Speicher (UT) | Externer Speicher (UT) |
---|---|
Interner Speicher des Telefons | herausnehmbare Secure Digital (SD) -Karte oder Micro-SD-Speicher |
Beispiel: 32 GB interner Speicher des Nexus 6P. | Beispiel: Speicherplatz in herausnehmbaren SD-Karten, die von Anbietern wie Samsung, Sandisk, Strontium, Transcend usw. bereitgestellt werden |
Laut Android Dokumentation / Anleitung - Googles Terminologie (GT)
Interner Speicher (GT):
Standardmäßig sind im internen Speicher gespeicherte Dateien für Ihre Anwendung privat und andere Anwendungen können nicht auf sie zugreifen (auch nicht auf den Benutzer).
Externer Speicher (GT):
Dies kann ein Wechseldatenträger (z. B. eine SD-Karte) oder ein interner (nicht entfernbarer) Speicher sein.
Externe Speicher (GT) können in zwei Typen eingeteilt werden:
Primärer externer Speicher | Sekundärer externer Speicher oder Wechselspeicher (GT) |
---|---|
Dies entspricht dem internen Speicher des Telefons (oder) des internen Speichers (UT). | Dies ist dasselbe wie ein entfernbarer Micro-SD-Kartenspeicher (oder) Externer Speicher (UT) |
Beispiel: 32 GB interner Speicher des Nexus 6P. | Beispiel: Speicherplatz in herausnehmbaren SD-Karten, die von Anbietern wie Samsung, Sandisk, Strontium, Transcend usw. bereitgestellt werden |
Auf diese Art von Speicher kann von Windows-PCs aus zugegriffen werden, indem Sie Ihr Telefon über ein USB-Kabel an den PC anschließen und in der USB-Optionsbenachrichtigung Kamera (PTP) auswählen. | Auf diese Art von Speicher kann von Windows-PCs aus zugegriffen werden, indem Sie Ihr Telefon über ein USB-Kabel an den PC anschließen und in der Benachrichtigung über USB-Optionen Dateiübertragung auswählen. |
In einer Nussschale,
Externer Speicher (GT) = Interner Speicher (UT) und Externer Speicher (UT)
Wechselspeicher (GT) = Externer Speicher (UT)
Interner Speicher (GT) hat keine Laufzeit in UT.
Lassen Sie mich klar erklären,
Interner Speicher (GT): Standardmäßig sind auf dem internen Speicher gespeicherte Dateien für Ihre Anwendung privat, und andere Anwendungen können nicht auf sie zugreifen. Ihr App-Benutzer kann auch nicht mit dem Dateimanager darauf zugreifen. auch nach Aktivierung der Option "Alle Dateien anzeigen" im Dateimanager. Um auf Dateien im internen Speicher (GT) zugreifen zu können, müssen Sie Ihr Android-Telefon rooten. Wenn der Benutzer Ihre Anwendung deinstalliert, werden diese Dateien außerdem entfernt / gelöscht.
Interner Speicher (GT) ist also NICHT das, was wir als internen 32/64 GB-Speicher des Nexus 6P meinen
Im Allgemeinen würde der Speicherort für den internen Speicher (GT) lauten: /data/data/your.application.package.appname/someDirectory/
Externer Speicher (GT):
Jedes Android-kompatible Gerät unterstützt einen freigegebenen "externen Speicher", den Sie zum Speichern von Dateien verwenden können. Auf dem externen Speicher gespeicherte Dateien sind weltweit lesbar und können vom Benutzer geändert werden, wenn USB-Massenspeicher zum Übertragen von Dateien auf einem Computer aktiviert werden.
Speicherort des externen Speichers (GT): Er kann sich irgendwo in Ihrem internen Speicher (UT) oder in Ihrem Wechselspeicher (GT) befinden, z. B. einer Micro-SD-Karte. Dies hängt vom OEM Ihres Handys und auch von der Android OS-Version ab.
Um Dateien auf dem externen Speicher (GT) lesen oder schreiben zu können, muss Ihre App die READ_EXTERNAL_STORAGE
oder WRITE_EXTERNAL_STORAGE
erwerben.
Zum Beispiel:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Wenn Sie Dateien sowohl lesen als auch schreiben müssen, müssen Sie nur die
WRITE_EXTERNAL_STORAGE
, da dies implizit auch Lesezugriff erfordert.
In External Storage (GT) können Sie auch App-private Dateien speichern
Aber,
Wenn der Benutzer Ihre Anwendung deinstalliert, werden dieses Verzeichnis und der gesamte Inhalt gelöscht.
Wann müssen Sie app-private Dateien im externen Speicher (GT) speichern?
Wenn Sie mit Dateien arbeiten, die nicht für andere Apps vorgesehen sind (z. B. grafische Texturen oder Soundeffekte, die nur Ihre App verwendet), sollten Sie ein privates Speicherverzeichnis auf dem externen Speicher verwenden
Ab Android 4.4 ist für das Lesen oder Schreiben von Dateien in den privaten Verzeichnissen der App nicht die
READ_EXTERNAL_STORAGE
oderWRITE_EXTERNAL_STORAGE
erforderlich. Sie können alsomaxSdkVersion
, dass die Berechtigung nur für die niedrigeren Versionen von Android angefordert werden soll, indem Sie das AttributmaxSdkVersion
hinzufügen:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
Methoden zum Speichern im internen Speicher (GT):
Beide Methoden sind in der Context- Klasse vorhanden
File getDir (String name, int mode)
File getFilesDir ()
Methoden zum Speichern im primären externen Speicher, dh internen Speicher (UT):
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
Am Anfang benutzten alle Environment.getExternalStorageDirectory () , das auf den Stamm des primären externen Speichers verwies. Daher wurde der primäre externe Speicher mit zufälligem Inhalt gefüllt.
Später wurden diese beiden Methoden hinzugefügt:
In der
Context
Klasse fügten sie getExternalFilesDir () hinzu und verweisen auf ein anwendungsspezifisches Verzeichnis im primären externen Speicher. Dieses Verzeichnis und sein Inhalt werden gelöscht, wenn die App deinstalliert wird.Environment.getExternalStoragePublicDirectory () für zentralisierte Orte zum Speichern bekannter Dateitypen wie Fotos und Filme. Dieses Verzeichnis und sein Inhalt werden NICHT gelöscht, wenn die App deinstalliert wird.
Methoden zum Speichern in Wechselmedien (GT), z. B. Micro-SD-Karte
Vor dem API-Level 19 gab es keine offizielle Möglichkeit , auf SD-Karte zu speichern. Aber viele könnten es mit inoffiziellen Bibliotheken oder APIs tun.
Offiziell wurde eine Methode in der Context
Klasse in API Level 19 (Android-Version 4.4 - Kitkat) eingeführt.
File[] getExternalFilesDirs (String type)
Sie gibt absolute Pfade an anwendungsspezifische Verzeichnisse auf allen freigegebenen / externen Speichergeräten zurück, in denen die Anwendung persistente Dateien ablegen kann, die ihr gehören. Diese Dateien sind in der Anwendung intern und für den Benutzer normalerweise nicht als Medium sichtbar.
Das heißt, es werden Pfade zu beiden Arten von externen Speichern (GT) zurückgegeben - internem Speicher und Micro-SD-Karte. Im Allgemeinen wäre der zweite Pfad der Speicherpfad der Micro-SD-Karte (jedoch nicht immer). Sie müssen es also überprüfen, indem Sie den Code mit dieser Methode ausführen.
Beispiel mit Code-Snippet:
Ich habe ein neues Android-Projekt mit leeren Aktivitäten erstellt und folgenden Code geschrieben
protected void onCreate(Bundle savedInstanceState)
-Methode von MainActivity.java
File internal_m1 = getDir("custom", 0);
File internal_m2 = getFilesDir();
File external_m1 = Environment.getExternalStorageDirectory();
File external_m2 = getExternalFilesDir(null);
File external_m2_Args = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File external_m3 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File[] external_AND_removable_storage_m1 = getExternalFilesDirs(null);
File[] external_AND_removable_storage_m1_Args = getExternalFilesDirs(Environment.DIRECTORY_PICTURES);
Nach dem Ausführen des obigen Codes
Ausgabe:
internal_m1: /data/data/your.application.package.appname/app_custom
internal_m2: /data/data/your.application.package.appname/files
external_m1: /storage/emulated/0
external_m2: /storage/emulated/0/Android/data/your.application.package.appname/files
external_m2_Args: /storage/emulated/0/Android/data/your.application.package.appname/files/Pictures
external_m3: /storage/emulated/0/Pictures
external_AND_removable_storage_m1 (first path):
/storage/emulated/0/Android/data/your.application.package.appname/files
external_AND_removable_storage_m1 (second path):
/storage/sdcard1/Android/data/your.application.package.appname/files
external_AND_removable_storage_m1_Args (first path):
/storage/emulated/0/Android/data/your.application.package.appname/files/Pictures
external_AND_removable_storage_m1_Args (second path): /storage/sdcard1/Android/data/your.application.package.appname/files/Pictures
Hinweis: Ich habe mein Telefon an einen Windows-PC angeschlossen. aktiviert beide Entwickleroptionen, USB-Debugging und führte diesen Code aus. Wenn Sie Ihr Telefon nicht anschließen ; Wenn Sie dies jedoch auf einem Android-Emulator ausführen, kann Ihre Ausgabe variieren. Mein Telefonmodell ist Coolpad Note 3 - läuft unter Android 5.1
Speicherorte auf meinem Handy:
Micro-SD-Speicherort : /storage/sdcard1
Interner Speicherort (UT) : /storage/sdcard0
.
Beachten Sie, dass /sdcard
& /storage/emulated/0
/sdcard
/storage/emulated/0
auch auf Internal Storage (UT) /sdcard
. Das sind aber Symlinks zu /storage/sdcard0
.
Um die verschiedenen Speicherpfade in Android genau zu verstehen, gehen Sie bitte diese Antwort durch
Haftungsausschluss: Alle oben genannten Speicherpfade sind Pfade auf meinem Telefon. Ihre Dateien werden möglicherweise nicht in denselben Speicherpfaden gespeichert. Da sich die Speicherorte / Pfade auf anderen Mobiltelefonen je nach Hersteller, Hersteller und unterschiedlichen Versionen des Android-Betriebssystems unterscheiden können.
Datenbank auf SD-Karte speichern (Backup DB auf SD)
public static Boolean ExportDB(String DATABASE_NAME , String packageName , String folderName){
//DATABASE_NAME including ".db" at the end like "mayApp.db"
String DBName = DATABASE_NAME.substring(0, DATABASE_NAME.length() - 3);
File data = Environment.getDataDirectory();
FileChannel source=null;
FileChannel destination=null;
String currentDBPath = "/data/"+ packageName +"/databases/"+DATABASE_NAME; // getting app db path
File sd = Environment.getExternalStorageDirectory(); // getting phone SD card path
String backupPath = sd.getAbsolutePath() + folderName; // if you want to set backup in specific folder name
/* be careful , foldername must initial like this : "/myFolder" . dont forget "/" at begin of folder name
you could define foldername like this : "/myOutterFolder/MyInnerFolder" and so on ...
*/
File dir = new File(backupPath);
if(!dir.exists()) // if there was no folder at this path , it create it .
{
dir.mkdirs();
}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
Date date = new Date();
/* use date including file name for arrange them and preventing to make file with the same*/
File currentDB = new File(data, currentDBPath);
File backupDB = new File(backupPath, DBName +"("+ dateFormat.format(date)+").db");
try {
if (currentDB.exists() && !backupDB.exists()) {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
return true;
}
return false;
} catch(IOException e) {
e.printStackTrace();
return false;
}
}
Rufen Sie diese Methode folgendermaßen auf:
ExportDB ("myDB.db", "com.example.exam", "/ myFolder");
Geräteverzeichnis abrufen:
Fügen Sie zuerst die Speicherberechtigung hinzu, um das Geräteverzeichnis zu lesen / abzurufen.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Erstellen Sie eine Modellklasse
//create one directory model class
//to store directory title and type in list
public class DirectoryModel {
String dirName;
int dirType; // set 1 or 0, where 0 for directory and 1 for file.
public int getDirType() {
return dirType;
}
public void setDirType(int dirType) {
this.dirType = dirType;
}
public String getDirName() {
return dirName;
}
public void setDirName(String dirName) {
this.dirName = dirName;
}
}
Erstellen Sie eine Liste mithilfe des Verzeichnismodells, um Verzeichnisdaten hinzuzufügen.
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
Rufen Sie das Verzeichnis mit folgender Methode ab.
//to fetch device directory
private void getDirectory(String currDir) { // pass device root directory
File f = new File(currDir);
File[] files = f.listFiles();
if (files != null) {
if (files.length > 0) {
rootDir.clear();
for (File inFile : files) {
if (inFile.isDirectory()) { //return true if it's directory
// is directory
DirectoryModel dir = new DirectoryModel();
dir.setDirName(inFile.toString().replace("/storage/emulated/0", ""));
dir.setDirType(0); // set 0 for directory
rootDir.add(dir);
} else if (inFile.isFile()) { // return true if it's file
//is file
DirectoryModel dir = new DirectoryModel();
dir.setDirName(inFile.toString().replace("/storage/emulated/0", ""));
dir.setDirType(1); // set 1 for file
rootDir.add(dir);
}
}
}
printDirectoryList();
}
}
Verzeichnisliste im Protokoll drucken
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
Verwendungszweck
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
Um innere Dateien / Ordner eines bestimmten Verzeichnisses abzurufen, verwenden Sie dieselbe Methode. Ändern Sie einfach das Argument, übergeben Sie den aktuell ausgewählten Pfad als Argument und behandeln Sie die Antwort.
So erhalten Sie die Dateierweiterung:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}