Android
FileIO mit Android
Suche…
Einführung
Das Lesen und Schreiben von Dateien in Android unterscheidet sich nicht vom Lesen und Schreiben von Dateien im Standard-Java. java.io
Paket kann verwendet werden. Es gibt jedoch einige spezifische Informationen zu den Ordnern, in die Sie schreiben dürfen, Berechtigungen allgemein und MTP-Problemumgehungen.
Bemerkungen
Android bietet die Möglichkeit, die Datei für mehrere Anwendungen freizugeben, wie hier dokumentiert. Dies ist nicht erforderlich, wenn nur eine App die Datei erstellt und verwendet.
Android bietet alternative Speicheroptionen wie freigegebene und private Einstellungen, gespeicherte Bundles und integrierte Datenbank. In einigen Fällen sind sie die bessere Wahl, als nur einfache Dateien zu verwenden.
Für Android-Aktivitäten gibt es einige spezifische Methoden, die wie ein Ersatz der Java-Standard-File-IO-Methoden aussehen. Zum Beispiel, anstatt für File.delete()
Sie können anrufen Context.deleteFile()
, und anstelle der Anwendung File.listFiles()
rekursiv können Sie anrufen Context.fileList()
die Liste aller Ihrer Anwendung bestimmte Dateien mit etwas weniger zu bekommen Code. Sie bieten jedoch keine zusätzlichen Funktionen über das Standardpaket java.io
hinaus.
Arbeitsordner erhalten
Sie erhalten Ihren Arbeitsordner, indem Sie die Methode getFilesDir()
für Ihre Aktivität aufrufen (Activity ist die zentrale Klasse in Ihrer Anwendung, die von Context erbt. Siehe hier ). Lesen ist nicht anders. Nur Ihre Anwendung hat Zugriff auf diesen Ordner.
Ihre Aktivität könnte zum Beispiel den folgenden Code enthalten:
File myFolder = getFilesDir();
File myFile = new File(myFolder, "myData.bin");
Rohes Array von Bytes schreiben
File myFile = new File(getFilesDir(), "myData.bin");
FileOutputStream out = new FileOutputStream(myFile);
// Write four bytes one two three four:
out.write(new byte [] { 1, 2, 3, 4}
out.close()
Es gibt nichts Android-spezifisches mit diesem Code. Wenn Sie häufig kleine Werte schreiben, verwenden Sie BufferedOutputStream , um den Verschleiß der geräteinternen SSD zu reduzieren.
Objekt serialisieren
Die alte, gute Java-Objektserialisierung steht Ihnen in Android zur Verfügung. Sie können serialisierbare Klassen definieren wie:
class Cirle implements Serializable {
final int radius;
final String name;
Circle(int radius, int name) {
this.radius = radius;
this.name = name;
}
}
und schreibe dann in den ObjectOutputStream:
File myFile = new File(getFilesDir(), "myObjects.bin");
FileOutputStream out = new FileOutputStream(myFile);
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(out));
oout.writeObject(new Circle(10, "One"));
oout.writeObject(new Circle(12, "Two"));
oout.close()
Die Java-Objektserialisierung kann entweder perfekt oder wirklich schlecht sein, je nachdem, was Sie damit machen möchten - außerhalb des Rahmens dieses Tutorials und manchmal auf Meinungen beruhend. Lesen Sie zuerst die Versionsverwaltung, wenn Sie sie verwenden möchten.
Auf externen Speicher schreiben (SD-Karte)
Sie können auch von einer auf vielen Android-Geräten vorhandenen Speicherkarte (SD-Karte) lesen und darauf schreiben. Auf Dateien an diesem Speicherort kann von anderen Programmen zugegriffen werden, auch direkt vom Benutzer, nachdem das Gerät über ein USB-Kabel an den PC angeschlossen und das MTP-Protokoll aktiviert wurde.
Das Auffinden der SD-Karte ist etwas problematischer. Die Environment- Klasse enthält statische Methoden, um "externe Verzeichnisse" zu erhalten, die sich normalerweise auf der SD-Karte befinden sollten. Außerdem wird angegeben, ob die SD-Karte überhaupt vorhanden ist und beschreibbar ist. Diese Frage enthält wertvolle Antworten, um sicherzustellen, dass der richtige Ort gefunden wird.
Für den Zugriff auf externen Speicher sind Berechtigungen in Ihrem Android-Manifest erforderlich:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Bei älteren Versionsberechtigungen von Android reicht es aus, diese Berechtigungen in Manifest zu setzen (der Benutzer muss während der Installation zustimmen). Ab Android 6.0 fordert Android den Benutzer jedoch beim ersten Zugriff zur Genehmigung auf, und Sie müssen diesen neuen Ansatz unterstützen. Ansonsten wird der Zugriff unabhängig von Ihrem Manifest verweigert.
In Android 6.0 müssen Sie zunächst die Erlaubnis prüfen und dann, falls nicht erteilt, diese anfordern. Die Codebeispiele finden Sie in dieser SO-Frage .
Problem mit "unsichtbaren MTP-Dateien" behoben.
Wenn Sie Dateien zum Exportieren über ein USB-Kabel an den Desktop mithilfe des MTP-Protokolls erstellen, besteht das Problem, dass neu erstellte Dateien nicht sofort im Dateiexplorer des angeschlossenen Desktop-PCs angezeigt werden. Um neue Dateien sichtbar zu machen, müssen Sie MediaScannerConnection aufrufen :
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), "theDocument.txt");
FileOutputStream out = new FileOutputStream(file)
... (write the document)
out.close()
MediaScannerConnection.scanFile(this, new String[] {file.getPath()}, null, null);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(file)));
Dieser MediaScannerConnection-Aufrufcode funktioniert nur für Dateien, nicht für Verzeichnisse. Das Problem wird in diesem Android-Fehlerbericht beschrieben . Dies kann für einige Versionen in der Zukunft oder auf einigen Geräten behoben sein.
Mit großen Dateien arbeiten
Kleine Dateien werden in Sekundenbruchteilen verarbeitet und Sie können sie anstelle des Codes lesen und schreiben, wo Sie dies benötigen. Wenn die Datei jedoch größer oder anderweitig langsamer verarbeitet werden muss, müssen Sie möglicherweise AsyncTask in Android verwenden, um mit der Datei im Hintergrund zu arbeiten:
class FileOperation extends AsyncTask<String, Void, File> {
@Override
protected File doInBackground(String... params) {
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), "bigAndComplexDocument.odf");
FileOutputStream out = new FileOutputStream(file)
... (write the document)
out.close()
return file;
} catch (IOException ex) {
Log.e("Unable to write", ex);
return null;
}
}
@Override
protected void onPostExecute(File result) {
// This is called when we finish
}
@Override
protected void onPreExecute() {
// This is called before we begin
}
@Override
protected void onProgressUpdate(Void... values) {
// Unlikely required for this example
}
}
}
und dann
new FileOperation().execute("Some parameters");
Diese SO-Frage enthält das vollständige Beispiel zum Erstellen und Aufrufen der AsyncTask. Lesen Sie auch die Frage zur Fehlerbehandlung , wie IOExceptions und andere Fehler behandelt werden.