Comment créer un répertoire automatiquement sur la carte SD

189

J'essaie d'enregistrer mon fichier à l'emplacement suivant
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); mais j'obtiens l'exception java.io.FileNotFoundException
Cependant, lorsque je mets le chemin comme "/sdcard/"il fonctionne.

Maintenant, je suppose que je ne suis pas en mesure de créer un répertoire automatiquement de cette façon.

Quelqu'un peut-il suggérer comment créer un directory and sub-directorycode d'utilisation?

Kshitij Aggarwal
la source

Réponses:

449

Si vous créez un objet File qui encapsule le répertoire de niveau supérieur, vous pouvez appeler sa méthode mkdirs () pour créer tous les répertoires nécessaires. Quelque chose comme:

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

Remarque: il peut être judicieux d'utiliser Environment.getExternalStorageDirectory () pour obtenir le répertoire "SD Card" car cela peut changer si un téléphone arrive avec autre chose qu'une carte SD (comme le flash intégré, a'la le iPhone). Dans tous les cas, vous devez garder à l'esprit que vous devez vous assurer qu'il est bien là car la carte SD peut être retirée.

MISE À JOUR: Depuis le niveau d'API 4 (1.6), vous devrez également demander l'autorisation. Quelque chose comme ça (dans le manifeste) devrait fonctionner:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Jeremy Logan
la source
1
oui, les tablettes Samsung publiées ultérieurement utilisent un flash intégré
CQM
2
n'oubliez pas d'ajouter à AndroidManifest.xml le droit d'écrire stackoverflow.com/a/4435708/579646
max4ever
1
Cela semble ne pas fonctionner si j'ai un sous-sous-dossier, comme /sdcard/com.my.code/data? Comment pourrais-je résoudre ça?
lony
En plus de créer ce répertoire aussi? Existe-t-il une commande comme «force» dans unix mkdir?
lony
4
Ne fonctionne pas sur KitKat, carte SD physique externe.
celoftis le
57

J'ai eu le même problème et je veux simplement ajouter qu'AndroidManifest.xml a également besoin de cette autorisation:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Daniel
la source
39

Voici ce qui fonctionne pour moi.

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

dans votre manifeste et le code ci-dessous

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
la source
chemin est le nom du dossier que vous souhaitez créer. Si vous avez envoyé un chemin comme MusicDownload .. Il devient automatiquement / sdcard / MusicDownload. Shajeel Afzal
shehzy
Il lève l'exception java.io.IOException: ouverture a échoué: ENOENT (aucun fichier ou répertoire de ce type)
Anand Savjani
24

En fait, j'ai utilisé une partie de @fiXedd asnwer et cela a fonctionné pour moi:

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

Assurez-vous que vous utilisez mkdirs () et non mkdir () pour créer le chemin complet

Amt87
la source
Comment est cette "partie" de la réponse @fixedd? Sa réponse était d'utiliser File.mkdirs(). Il a ensuite montré un exemple d'utilisation.
Doomsknight
En fait, je ne me souviens pas quelle était la différence, mais je pense qu'il y a eu quelques modifications ... Au fait, j'ai mentionné que j'avais utilisé sa réponse pour obtenir la solution
Amt87
12

Avec l'API 8 et les versions ultérieures, l'emplacement de la carte SD a changé. La réponse de @ fiXedd est bonne, mais pour un code plus sûr, vous devriez utiliser Environment.getExternalStorageState()pour vérifier si le média est disponible. Ensuite, vous pouvez utiliser getExternalFilesDir()pour accéder au répertoire souhaité (en supposant que vous utilisez l'API 8 ou une version supérieure).

Vous pouvez en savoir plus dans la documentation du SDK .

Nick Ruiz
la source
8

Assurez-vous que le stockage externe est présent: 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
la source
6

N'oubliez pas de vous assurer qu'il n'y a pas de caractères spéciaux dans les noms de vos fichiers / dossiers. M'est arrivé avec ":" lorsque je définissais les noms de dossier à l'aide de variables

caractères non autorisés dans les noms de fichiers / dossiers

"* /: <>? \ |

U peut trouver ce code utile dans un tel cas.

Le code ci-dessous supprime tous les ":" et les remplace par "-"

//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
la source
+1 ya j'ai aussi essayé avec: et j'ai eu une erreur et j'ai finalement trouvé ce problème et supprimé: et tous les autres caractères spéciaux.
Ganapathy C
6

J'ai fait face au même problème. Il existe deux types d'autorisations dans Android:

  • Dangereux (accès aux contacts, écriture sur stockage externe ...)
  • Normal (les autorisations normales sont automatiquement approuvées par Android tandis que les autorisations dangereuses doivent être approuvées par les utilisateurs d'Android.)

Voici la stratégie pour obtenir des autorisations dangereuses dans Android 6.0

  • Vérifiez si vous avez l'autorisation accordée
  • Si votre application est déjà autorisée, continuez et exécutez normalement.
  • Si votre application n'a pas encore l'autorisation, demandez à l'utilisateur de l'approuver
  • Écoutez l'approbation des utilisateurs dans onRequestPermissionsResult

Voici mon cas: j'ai besoin d'écrire sur un stockage externe.

Tout d'abord, je vérifie si j'ai l'autorisation:

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

Vérifiez ensuite l'approbation de l'utilisateur:

@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
la source
5

J'étais confronté au même problème, incapable de créer un répertoire sur Galaxy S, mais j'ai pu le créer avec succès sur Nexus et Samsung Droid. Comment j'ai résolu le problème en ajoutant la ligne de code suivante:

File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/"+getPackageName()+"/");
dir.mkdirs();
Garima Srivastava
la source
5
File sdcard = Environment.getExternalStorageDirectory();
File f=new File(sdcard+"/dor");
f.mkdir();

cela créera un dossier nommé dor dans votre sdcard. puis pour récupérer le fichier par exemple: nomfichier.json qui est inséré manuellement dans le dossier dor . Comme:

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

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

et n'oubliez pas d'ajouter du code dans le manifeste

jayant singh
la source
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
la source
3

Je viens de terminer le post de Vijay ...


Manifeste

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

Fonction

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

Usage

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

Vous pourriez vérifier les erreurs

if(createDirIfNotExists("mydir/")){
     //Directory Created Success
}
else{
    //Error
}
Ismael Di Vita
la source
3

Cela créera un dossier dans sdcard avec le nom de dossier que vous fournissez.

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

Vous pouvez utiliser / sdcard / au lieu de Environment.getExternalStorageDirectory ()

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

File dbdir = new File(DB_PATH);
dbdir.mkdirs();
Peter Drinnan
la source
4
Non, vous ne devez pas utiliser un chemin codé en dur au lieu d'appeler l'API appropriée. Cela introduit une dépendance imprudente sur les détails d'une implémentation particulière.
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);

        }
    });`
Vishnu Namboodiri
la source