Cómo crear directorio automáticamente en la tarjeta SD


Estoy tratando de guardar mi archivo en la siguiente ubicación
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); pero estoy recibiendo la excepción java.io.FileNotFoundException
Sin embargo, cuando pongo el camino como "/sdcard/" funciona.

Ahora estoy asumiendo que no soy capaz de crear directorio automáticamente de esta manera.

¿Puede alguien sugerir cómo crear un directory and sub-directory usando código?

Author: user55924, 2010-01-25

15 answers

Si crea un objeto File que envuelve el directorio de nivel superior, puede llamar a su método mkdirs() para construir todos los directorios necesarios. Algo como:

// 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: Podría ser prudente usar Ambiente.getExternalStorageDirectory () para obtener el directorio "Tarjeta SD", ya que esto podría cambiar si aparece un teléfono que tiene algo que no sea una tarjeta SD (como flash incorporado, a'la el iPhone). De cualquier manera usted debe tener en cuenta que usted necesidad de comprobar para asegurarse de que realmente está allí como la tarjeta SD puede ser eliminado.

ACTUALIZACIÓN: Desde el nivel de API 4 (1.6) también tendrá que solicitar el permiso. Algo como esto (en el manifiesto) debería funcionar:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 428
Author: Jeremy Logan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-18 21:42:54

Tenía el mismo problema y solo quiero añadir que AndroidManifest.xml también necesita este permiso:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 57
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-15 22:07:54

Esto es lo que funciona para mí.

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

En su manifiesto y el siguiente código

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;
}
 38
Author: Vijay Kumar A B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-20 05:29:09

En realidad usé parte de @fiXedd asnwer y funcionó para mí:

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

Asegúrese de que está usando mkdirs() no mkdir() para crear la ruta completa

 21
Author: Amt87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-03 09:17:53

Con API 8 y superior, la ubicación de la tarjeta SD ha cambiado. La respuesta de @fiXedd es buena, pero para un código más seguro, debe usar Environment.getExternalStorageState() para verificar si el medio está disponible. A continuación, puede utilizar getExternalFilesDir() para navegar hasta el directorio que desee (suponiendo que esté utilizando API 8 o superior).

Puede leer más en la documentación del SDK .

 12
Author: Nick Ruiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-01 15:36:16

Asegúrese de que el almacenamiento externo esté presente: 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);
    }
 8
Author: Parth mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-29 11:08:50

Me enfrenté al mismo problema. Hay dos tipos de permisos en Android:

  • Peligroso (acceso a contactos, escribir en almacenamiento externo...)
  • Normal (Los permisos normales son aprobados automáticamente por Android, mientras que los permisos peligrosos deben ser aprobados por los usuarios de Android.)

Aquí está la estrategia para obtener permisos peligrosos en Android 6.0

  • Compruebe si tiene el permiso concedido
  • Si su aplicación ya está concedido el permiso, seguir adelante y actuar normalmente.
  • Si tu app aún no tiene el permiso, pide al usuario que apruebe
  • Escuchar la aprobación del usuario en onRequestPermissionsResult

Este es mi caso: necesito escribir en un almacenamiento externo.

Primero, compruebo si tengo el permiso:

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

Luego verifique la aprobación del usuario:

@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();
            }
        }
    }    
}
 6
Author: Syed Abdul Basit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-22 14:55:39

Me enfrentaba al mismo problema, incapaz de crear el directorio en Galaxy S, pero fue capaz de crear con éxito en Nexus y Samsung Droid. Cómo lo arreglé fue agregando la siguiente línea de código:

File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/"+getPackageName()+"/");
dir.mkdirs();
 5
Author: Garima Srivastava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-17 15:48:33

No olvide asegurarse de que no tiene caracteres especiales en los nombres de sus archivos/carpetas. Me sucedió con": "cuando estaba configurando nombres de carpetas usando variables

No se permiten caracteres en los nombres de archivos/carpetas

" * / : ? \ |

U puede encontrar este código útil en tal caso.

El siguiente código elimina todos los": "y los reemplaza 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");
        }
    }
 5
Author: Praveen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-20 01:46:08
File sdcard = Environment.getExternalStorageDirectory();
File f=new File(sdcard+"/dor");
f.mkdir();

Esto creará una carpeta llamada dor en su tarjeta SD. a continuación, para obtener el archivo para eg-filename.json que se inserta manualmente en la carpeta dor. Como:

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

Y no olvides agregar código en manifest

 5
Author: jayant singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-30 16:08:08
     //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);
 4
Author: vikseln,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-14 09:07:43

Solo completando el post de Vijay...


Manifiesto

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

Function

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

Puede comprobar si hay errores

if(createDirIfNotExists("mydir/")){
     //Directory Created Success
}
else{
    //Error
}
 3
Author: Ismael Di Vita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-28 12:19:33

Esto hará que la carpeta en la tarjeta SD con el nombre de la carpeta que proporcione.

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Folder name");
        if (!file.exists()) {
            file.mkdirs();
        }
 3
Author: Shweta Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-02 06:03:40

Puede usar /sdcard/ en lugar de Environment.getExternalStorageDirectory ()

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

File dbdir = new File(DB_PATH);
dbdir.mkdirs();
 1
Author: Peter Drinnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-25 01:44:18
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);

        }
    });`
 1
Author: Vishnu Namboodiri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 07:08:01