Jak automatycznie utworzyć katalog na karcie SD


189

Próbuję zapisać plik w następującej lokalizacji,
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); ale otrzymuję wyjątek. java.io.FileNotFoundException
Jednak po umieszczeniu ścieżki w trakcie "/sdcard/"jej działania.

Teraz zakładam, że nie jestem w stanie automatycznie utworzyć katalogu w ten sposób.

Czy ktoś może zasugerować, jak utworzyć directory and sub-directorykod używający?

Odpowiedzi:


449

Jeśli utworzysz obiekt File, który otacza katalog najwyższego poziomu, możesz nazwać go metodą mkdirs () w celu zbudowania wszystkich potrzebnych katalogów. Coś jak:

// create a File object for the parent directory
File wallpaperDirectory = new File("/sdcard/Wallpaper/");
// have the object build the directory structure, if needed.
wallpaperDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(wallpaperDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);

Uwaga: rozsądne może być użycie Environment.getExternalStorageDirectory () do uzyskania katalogu „SD Card”, ponieważ może się to zmienić, jeśli pojawi się telefon, który ma coś innego niż kartę SD (np. Wbudowaną pamięć flash, a iPhone). Tak czy inaczej, należy pamiętać, że należy sprawdzić, czy rzeczywiście tam jest, ponieważ karta SD może zostać wyjęta.

AKTUALIZACJA: Od poziomu API 4 (1.6) musisz również poprosić o pozwolenie. Coś takiego (w manifeście) powinno działać:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

1
tak, później wydane tablety Samsung wykorzystują wbudowaną pamięć flash
CQM

2
nie zapomnij dodać do
pliku

1
Wygląda na to, że to nie działa, jeśli mam podfolder, na przykład /sdcard/com.my.code/data? Jak mogę to rozwiązać?
lony

Oprócz tworzenia tego katalogu też? Czy w unix mkdir istnieje polecenie takie jak „force”?
lony

4
Nie działa na zewnętrznej, fizycznej karcie SD KitKat.
celoftis

57

Miałem ten sam problem i chcę tylko dodać, że plik AndroidManifest.xml wymaga również tego uprawnienia:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

39

Oto, co działa dla mnie.

 uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 

w swoim manifeście i poniższym kodzie

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

ścieżka to nazwa folderu, który chcesz utworzyć. Jeśli wysłałeś ścieżkę jak MusicDownload .. Automatycznie staje się / sdcard / MusicDownload. Shajeel Afzal
shehzy

Zgłasza wyjątek java.io.IOException: open failed: ENOENT (Brak takiego pliku lub katalogu)
Anand Savjani

24

Właściwie użyłem części asfwer @fiXedd i zadziałało to dla mnie:

  //Create Folder
  File folder = new File(Environment.getExternalStorageDirectory().toString()+"/Aqeel/Images");
  folder.mkdirs();

  //Save the path as a string value
  String extStorageDirectory = folder.toString();

  //Create New file and name it Image2.PNG
  File file = new File(extStorageDirectory, "Image2.PNG");

Upewnij się, że używasz mkdirs (), a nie mkdir () do utworzenia pełnej ścieżki


Jaka jest ta „część” odpowiedzi @fixedd? Jego odpowiedzią było użyć File.mkdirs(). Następnie pokazał przykład użycia go.
Doomsknight

Właściwie nie pamiętam, jaka była różnica, ale myślę, że było kilka zmian ... Przy okazji wspomniałem, że skorzystałem z jego odpowiedzi, aby uzyskać rozwiązanie
Amt87

12

W przypadku API 8 i nowszych położenie karty SD uległo zmianie. Odpowiedź @ fiXedd jest dobra, ale dla bezpieczniejszego kodu należy użyć, Environment.getExternalStorageState()aby sprawdzić, czy nośnik jest dostępny. Następnie możesz użyć, getExternalFilesDir()aby przejść do wybranego katalogu (zakładając, że używasz interfejsu API 8 lub nowszego).

Możesz przeczytać więcej w dokumentacji SDK .


8

Upewnij się, że dostępna jest pamięć zewnętrzna: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

private boolean isExternalStoragePresent() {

        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;
        }
        if (!((mExternalStorageAvailable) && (mExternalStorageWriteable))) {
            Toast.makeText(context, "SD card not present", Toast.LENGTH_LONG)
                    .show();

        }
        return (mExternalStorageAvailable) && (mExternalStorageWriteable);
    }

6

Nie zapomnij upewnić się, że w nazwach plików / folderów nie ma żadnych znaków specjalnych. Zdarzyło mi się, gdy „:” ustawiałem nazwy folderów przy użyciu zmiennych

niedozwolone znaki w nazwach plików / folderów

„* /: <>? \ |

W takim przypadku kod może być pomocny.

Poniższy kod usuwa wszystkie „:” i zastępuje je „-”

//actualFileName = "qwerty:asdfg:zxcvb" say...

    String[] tempFileNames;
    String tempFileName ="";
    String delimiter = ":";
    tempFileNames = actualFileName.split(delimiter);
    tempFileName = tempFileNames[0];
    for (int j = 1; j < tempFileNames.length; j++){
        tempFileName = tempFileName+" - "+tempFileNames[j];
    }
    File file = new File(Environment.getExternalStorageDirectory(), "/MyApp/"+ tempFileName+ "/");
    if (!file.exists()) {
        if (!file.mkdirs()) {
        Log.e("TravellerLog :: ", "Problem creating Image folder");
        }
    }

+1, ja też próbowałem z: i dostałem błąd, w końcu znalazłem ten problem i usunąłem: i wszystkie inne znaki specjalne.
Ganapathy C

6

Napotkałem ten sam problem. Istnieją dwa rodzaje uprawnień w Androidzie:

  • Niebezpieczne (dostęp do kontaktów, zapisywanie w pamięci zewnętrznej ...)
  • Normalne (Normalne uprawnienia są automatycznie zatwierdzane przez Androida, podczas gdy niebezpieczne uprawnienia muszą być zatwierdzane przez użytkowników Androida).

Oto strategia uzyskiwania niebezpiecznych uprawnień w systemie Android 6.0

  • Sprawdź, czy masz pozwolenie
  • Jeśli Twoja aplikacja ma już uprawnienia, śmiało i działaj normalnie.
  • Jeśli Twoja aplikacja nie ma jeszcze pozwolenia, poproś użytkownika o zatwierdzenie
  • Słuchaj zatwierdzenia użytkownika w onRequestPermissionsResult

Oto moja sprawa: muszę pisać w pamięci zewnętrznej.

Najpierw sprawdzam, czy mam pozwolenie:

...
private static final int REQUEST_WRITE_STORAGE = 112;
...
boolean hasPermission = (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
    ActivityCompat.requestPermissions(parentActivity,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_WRITE_STORAGE);
}

Następnie sprawdź zgodę użytkownika:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case REQUEST_WRITE_STORAGE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //reload my activity with permission granted or use the features what required the permission
            } else
            {
                Toast.makeText(parentActivity, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
            }
        }
    }    
}

5

Miałem ten sam problem, nie mogłem utworzyć katalogu na Galaxy S, ale udało mi się go utworzyć z powodzeniem na Nexusie i Samsungu Droidie. Jak to naprawiłem, dodając następujący wiersz kodu:

File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/"+getPackageName()+"/");
dir.mkdirs();

5
File sdcard = Environment.getExternalStorageDirectory();
File f=new File(sdcard+"/dor");
f.mkdir();

spowoduje to utworzenie folderu o nazwie dor na twojej karcie SD. następnie, aby pobrać plik np. nazwa_pliku.json, który jest ręcznie wstawiany do folderu dor . Lubić:

 File file1 = new File(sdcard,"/dor/fitness.json");
 .......
 .....

<używa-uprawnień android: nazwa = "android.permission.WRITE_EXTERNAL_STORAGE" />

i nie zapomnij dodać kodu w manifeście


4
     //Create File object for Parent Directory
File wallpaperDir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +File.separator + "wallpaper");
if (!wallpaperDir.exists()) {
wallpaperDir.mkdir();
}


File out = new File(wallpaperDir, wallpaperfile);
FileOutputStream outputStream = new FileOutputStream(out);

3

Właśnie uzupełniam wpis Vijay ...


Oczywisty

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

Funkcjonować

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

Stosowanie

createDirIfNotExists("mydir/"); //Create a directory sdcard/mydir
createDirIfNotExists("mydir/myfile") //Create a directory and a file in sdcard/mydir/myfile.txt

Możesz sprawdzić błędy

if(createDirIfNotExists("mydir/")){
     //Directory Created Success
}
else{
    //Error
}

3

Spowoduje to utworzenie folderu w sdcard z podaną nazwą folderu.

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Folder name");
        if (!file.exists()) {
            file.mkdirs();
        }

1

Możesz użyć / sdcard / zamiast Environment.getExternalStorageDirectory ()

private static String DB_PATH = "/sdcard/Android/data/com.myawesomeapp.app/";

File dbdir = new File(DB_PATH);
dbdir.mkdirs();

4
Nie, nie powinieneś używać twardej ścieżki zamiast wywoływania odpowiedniego API. Takie postępowanie wprowadza niemądrą zależność od szczegółów konkretnej implementacji.
Chris Stratton

1
ivmage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            startActivityForResult(i, RESULT_LOAD_IMAGE_ADD);

        }
    });`
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.