Come creare automaticamente la directory sulla scheda SD


189

Sto provando a salvare il mio file nella seguente posizione
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); ma ottengo l'eccezione java.io.FileNotFoundException
Tuttavia, quando inserisco il percorso come "/sdcard/"funziona.

Ora presumo che non sia in grado di creare automaticamente la directory in questo modo.

Qualcuno può suggerire come creare un directory and sub-directorycodice usando?

Risposte:


449

Se si crea un oggetto File che avvolge la directory di livello superiore, è possibile chiamare il metodo mkdirs () per creare tutte le directory necessarie. Qualcosa di simile a:

// 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);

Nota: potrebbe essere saggio utilizzare Environment.getExternalStorageDirectory () per ottenere la directory "Scheda SD" poiché ciò potrebbe cambiare se arriva un telefono che ha qualcosa di diverso da una scheda SD (come un flash incorporato, come i phone). In entrambi i casi è necessario tenere presente che è necessario verificare per accertarsi che sia effettivamente presente poiché la scheda SD potrebbe essere rimossa.

AGGIORNAMENTO: da API Level 4 (1.6) dovrai anche richiedere l'autorizzazione. Qualcosa del genere (nel manifest) dovrebbe funzionare:

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

1
sì, i tablet Samsung successivamente rilasciati utilizzano il flash incorporato
CQM

2
non dimenticare di aggiungere alla AndroidManifest.xml il diritto di scrivere stackoverflow.com/a/4435708/579646
max4ever

1
Sembra che non funzioni se ho una sottocartella, come /sdcard/com.my.code/data? Come ho potuto risolvere questo?
pazzo

Oltre a creare anche questa directory? Esiste un comando come 'force' in unix mkdir?
pazzo

4
Non funziona su KitKat, sdcard fisica, esterna.
celoftis,

57

Aveva lo stesso problema e volevo solo aggiungere che AndroidManifest.xml necessita anche di questa autorizzazione:

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

39

Ecco cosa funziona per me.

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

nel tuo manifest e nel codice seguente

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;
}

percorso è il nome della cartella che si desidera creare. Se hai inviato un percorso come MusicDownload .. Diventa automaticamente / sdcard / MusicDownload. Shajeel Afzal
shehzy l'

Genera eccezione java.io.IOException: apertura non riuscita: ENOENT (nessun file o directory di questo tipo)
Anand Savjani,

24

In realtà ho usato parte di @fiXedd asnwer e ha funzionato per me:

  //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");

Assicurati di utilizzare mkdirs () non mkdir () per creare il percorso completo


Come risponde questa "parte" di @fixedd? La sua risposta era usare File.mkdirs(). Ha quindi mostrato un esempio di utilizzo.
Doomsknight,

In realtà non riesco a ricordare quale sia stata la differenza, ma penso che ci siano state alcune modifiche ... A proposito, ho detto che ho usato la sua risposta per ottenere la soluzione
Amt87

12

Con API 8 e successive, la posizione della scheda SD è cambiata. La risposta di @ fiXedd è buona, ma per un codice più sicuro, dovresti usare Environment.getExternalStorageState()per verificare se il supporto è disponibile. Quindi è possibile utilizzare getExternalFilesDir()per accedere alla directory desiderata (presupponendo che si stia utilizzando API 8 o successiva).

Puoi leggere di più nella documentazione dell'SDK .


8

Assicurarsi che sia presente memoria esterna: 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

Non dimenticare di assicurarti di non avere caratteri speciali nei nomi di file / cartelle. Mi è successo con ":" quando stavo impostando i nomi delle cartelle usando le variabili

caratteri non ammessi nei nomi di file / cartelle

"* /: <>? \ |

In questo caso potresti trovare utile questo codice.

Il codice seguente rimuove tutto ":" e li sostituisce con "-"

//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 anche io ho provato con: e ho ricevuto un errore e finalmente ho trovato quel problema e rimosso: e tutti gli altri caratteri speciali.
Ganapathy C

6

Ho affrontato lo stesso problema. Esistono due tipi di autorizzazioni in Android:

  • Pericoloso (accesso ai contatti, scrittura su memoria esterna ...)
  • Normale (le autorizzazioni normali vengono approvate automaticamente da Android mentre le autorizzazioni pericolose devono essere approvate dagli utenti Android.)

Ecco la strategia per ottenere autorizzazioni pericolose in Android 6.0

  • Controlla se hai il permesso concesso
  • Se alla tua app è già stata concessa l'autorizzazione, vai avanti ed esegui normalmente.
  • Se la tua app non dispone ancora dell'autorizzazione, chiedi all'utente di approvare
  • Ascolta l'approvazione dell'utente in onRequestPermissionsResult

Ecco il mio caso: devo scrivere su un archivio esterno.

Innanzitutto, controllo se ho l'autorizzazione:

...
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);
}

Quindi controllare l'approvazione dell'utente:

@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

Stavo affrontando lo stesso problema, non ero in grado di creare directory su Galaxy S ma ero in grado di crearlo con successo su Nexus e Samsung Droid. Come l'ho risolto aggiungendo la seguente riga di codice:

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

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

questo creerà una cartella denominata dor nella tua sdcard. quindi per recuperare il file per es. nomefile.json che viene inserito manualmente nella cartella dor . Piace:

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

<usa-permesso android: nome = "android.permission.WRITE_EXTERNAL_STORAGE" />

e non dimenticare di aggiungere il codice in manifest


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

Sto completando il post di Vijay ...


Manifesto

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

Funzione

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;
}

uso

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

È possibile verificare la presenza di errori

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

3

Questo renderà la cartella in sdcard con il nome della cartella fornito.

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

1

Puoi usare / sdcard / invece di Environment.getExternalStorageDirectory ()

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

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

4
No, non dovresti usare un percorso hard coded invece di chiamare l'API corretta. In questo modo si introduce una dipendenza poco saggia dai dettagli di una particolare implementazione.
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);

        }
    });`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.