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?

Kshitij Aggarwal
źródło

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" />
Jeremy Logan
źródło
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" />
Daniel
źródło
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;
}
Vijay Kumar AB
źródło
ś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

Amt87
źródło
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 .

Nick Ruiz
źródło
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);
    }
Parth mehta
źródło
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");
        }
    }
Praveen
źródło
+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();
            }
        }
    }    
}
Syed Abdul Basit
źródło
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();
Garima Srivastava
źródło
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

jayant singh
źródło
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);
Vikseln
źródło
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
}
Ismael Di Vita
źródło
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();
        }
Shweta Chauhan
źródło
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();
Peter Drinnan
źródło
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);

        }
    });`
Wisznu Namboodiri
źródło