Wie schreibt man in einen Ordner auf einer SD-Karte in Android?

82

Ich verwende den folgenden Code, um eine Datei von meinem Server herunterzuladen und sie dann in das Stammverzeichnis der SD-Karte zu schreiben. Alles funktioniert einwandfrei:

package com.downloader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.os.Environment;
import android.util.Log;

public class Downloader {

    public void DownloadFile(String fileURL, String fileName) {
        try {
            File root = Environment.getExternalStorageDirectory();
            URL u = new URL(fileURL);
            HttpURLConnection c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();
            FileOutputStream f = new FileOutputStream(new File(root, fileName));

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = in.read(buffer)) > 0) {
                f.write(buffer, 0, len1);
            }
            f.close();
        } catch (Exception e) {
            Log.d("Downloader", e.getMessage());
        }

    }
}

Verwenden Environment.getExternalStorageDirectory();bedeutet jedoch, dass die Datei immer in das Stammverzeichnis geschrieben wird /mnt/sdcard. Ist es möglich, einen bestimmten Ordner anzugeben, in den die Datei geschrieben werden soll?

Beispielsweise: /mnt/sdcard/myapp/downloads

RailsSon
quelle
12
Denken Sie auch daran, die Berechtigungen im Manifest hinzuzufügen, damit dies funktioniert. <Verwendet-Berechtigung android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
timemirror

Antworten:

161
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/dir1/dir2");
dir.mkdirs();
File file = new File(dir, "filename");

FileOutputStream f = new FileOutputStream(file);
...
Plugmind
quelle
1
Stellen Sie sicher, dass Sie alle Kleinbuchstaben in Ihrem Verzeichnis und den Dateinamen verwenden.
BeccaP
1
Darf ich wissen, was es mit "/ dir1 / dir2" bedeutet und ohne dies kann ich meine Datei nicht in SD-Karte speichern ah?
AndroidOptimist
16
Laut doc: Hinweis:
bereitgestellt werden kann
1
@NeonWarge siehe hier
mr5
Warnung: getExternalStorageDirectory()war in API 29 veraltet.
Josh Correia
29

Berechtigung zum Android-Manifest hinzufügen

Fügen Sie diese WRITE_EXTERNAL_STORAGE-Berechtigung zu Ihrem Anwendungsmanifest hinzu.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your.company.package"
    android:versionCode="1"
    android:versionName="0.1">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <!-- ... -->
    </application>
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest> 

Überprüfen Sie die Verfügbarkeit des externen Speichers

Sie sollten immer zuerst die Verfügbarkeit prüfen. Ein Ausschnitt aus der offiziellen Android-Dokumentation zum externen Speicher .

boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();

if (Environment.MEDIA_MOUNTED.equals(state)) {
    // We can read and write the media
    mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
    // We can only read the media
    mExternalStorageAvailable = true;
    mExternalStorageWriteable = false;
} else {
    // Something else is wrong. It may be one of many other states, but all we need
    //  to know is we can neither read nor write
    mExternalStorageAvailable = mExternalStorageWriteable = false;
}

Verwenden Sie eine Schreibmaschine

Zu guter Letzt vergessen Sie das FileOutputStreamund verwenden FileWriterstattdessen ein. Weitere Informationen zu dieser Klasse finden Sie im FileWriter-Javadoc . Möglicherweise möchten Sie hier weitere Fehlerbehandlungen hinzufügen, um den Benutzer zu informieren.

// get external storage file reference
FileWriter writer = new FileWriter(getExternalStorageDirectory()); 
// Writes the content to the file
writer.write("This\n is\n an\n example\n"); 
writer.flush();
writer.close();
hcpl
quelle
1
Die Autoren des Buches, das ich lese, empfehlen die Verwendung von a FileOutputStream(nun, es werden die Alternativen nicht behandelt). Warum ist es besser, FileWriterstattdessen das zu verwenden - ist es schneller / zuverlässiger / etwas anderes?
Aga
3
@aga FileWriterbietet praktische Methoden zum direkten Schreiben von Strings, die auf einem nicht vorhanden sind FileOutputStream. Wenn Sie keine Textdateien schreiben, FileWriterist dies keine große Hilfe. In der Tat, wenn Sie eine Bilddatei schreiben , kann es überhaupt nicht wirklich mit einem gemacht FileWriter werden. Wenn Sie wirklich eine schöne API für Text wollen, wickeln Sie Ihre FileOutputStreamin eine PrintStreamund Sie haben alle die gleichen Methoden wie System.out.
Ian McLaird
1
Warum kann ich die Datei auf meiner SD-Karte nicht finden, nachdem die Datei erfolgreich geschrieben wurde?
Jemand irgendwo
2

Die Antwort finden Sie hier - http://mytechead.wordpress.com/2014/01/30/android-create-a-file-and-write-to-external-storage/

Es sagt,

/**

* Method to check if user has permissions to write on external storage or not

*/

public static boolean canWriteOnExternalStorage() {
   // get the state of your external storage
   String state = Environment.getExternalStorageState();
   if (Environment.MEDIA_MOUNTED.equals(state)) {
    // if storage is mounted return true
      Log.v("sTag", "Yes, can write to external storage.");
      return true;
   }
   return false;
}

und dann verwenden wir diesen Code, um tatsächlich in den externen Speicher zu schreiben:

// get the path to sdcard
File sdcard = Environment.getExternalStorageDirectory();
// to this path add a new directory path
File dir = new File(sdcard.getAbsolutePath() + "/your-dir-name/");
// create this directory if not already created
dir.mkdir();
// create the file in which we will write the contents
File file = new File(dir, "My-File-Name.txt");
FileOutputStream os = outStream = new FileOutputStream(file);
String data = "This is the content of my file";
os.write(data.getBytes());
os.close();

Und das ist es. Wenn Sie jetzt Ihren Ordner / sdcard / your-dir-name / besuchen, wird eine Datei mit dem Namen - My-File-Name.txt mit dem im Code angegebenen Inhalt angezeigt.

PS: - Sie benötigen die folgende Erlaubnis -

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Alchimist
quelle
2
Das Verzeichnis /sdcard/ist nicht immer die SD-Karte.
CurlyCorvus
Ich stimme Curly zu. Auf meinem Telefon gibt die Methode getExternalStorageDirectory einen emulierten Speicher zurück, bei dem es sich nicht um die SD-Karte handelt.
Spindizzy
-1

Um eine Datei zum Herunterladen oder Musikordner in SDCard herunterzuladen

File downlodDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);// or DIRECTORY_PICTURES

Und vergessen Sie nicht, diese Erlaubnis im Manifest hinzuzufügen

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
AndroidGeek
quelle
Wird dieser Download nicht in den Ordner "Downloads" anstatt auf eine SD-Karte durchgeführt?
Josh Correia