Creating a directory in /sdcard fails

AndroidFileDirectoryIo

Android Problem Overview


I have been trying to create a directory in /sdcard programmatically, but it's not working. The code below always outputs directory not created.

boolean success = (new File("/sdcard/map")).mkdir(); 
if (!success) {
    Log.i("directory not created", "directory not created");
} else {
    Log.i("directory created", "directory created");
}

Android Solutions


Solution 1 - Android

There are three things to consider here:

  1. Don't assume that the sd card is mounted at /sdcard (May be true in the default case, but better not to hard code.). You can get the location of sdcard by querying the system:

    Environment.getExternalStorageDirectory();
    
  2. You have to inform Android that your application needs to write to external storage by adding a uses-permission entry in the AndroidManifest.xml file:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
  3. If this directory already exists, then mkdir is going to return false. So check for the existence of the directory, and then try creating it if it does not exist. In your component, use something like:

    File folder = new File(Environment.getExternalStorageDirectory() + "/map");
    boolean success = true;
    if (!folder.exists()) {
        success = folder.mkdir();
    }
    if (success) {
        // Do something on success
    } else {
        // Do something else on failure 
    }
    

Solution 2 - Android

I had same issue after I updated my Android phone to 6.0 (API level 23). The following solution works on me. Hopefully it helps you as well.

Please check your android version. If it is >= 6.0 (API level 23), you need to not only include

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

in your AndroidManifest.xml, but also request permission before calling mkdir(). Code snopshot.

public static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
public int mkFolder(String folderName){ // make a folder under Environment.DIRECTORY_DCIM
    String state = Environment.getExternalStorageState();
    if (!Environment.MEDIA_MOUNTED.equals(state)){
        Log.d("myAppName", "Error: external storage is unavailable");
        return 0;
    }
    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        Log.d("myAppName", "Error: external storage is read only.");
        return 0;
    }
    Log.d("myAppName", "External storage is not read only or unavailable");

    if (ContextCompat.checkSelfPermission(this, // request permission when it is not granted. 
            Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        Log.d("myAppName", "permission:WRITE_EXTERNAL_STORAGE: NOT granted!");
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
    File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
    int result = 0;
    if (folder.exists()) {
        Log.d("myAppName","folder exist:"+folder.toString());
        result = 2; // folder exist
    }else{
        try {
            if (folder.mkdir()) {
                Log.d("myAppName", "folder created:" + folder.toString());
                result = 1; // folder created
            } else {
                Log.d("myAppName", "creat folder fails:" + folder.toString());
                result = 0; // creat folder fails
            }
        }catch (Exception ecp){
            ecp.printStackTrace();
        }
    }
    return result;
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

More information please read "Requesting Permissions at Run Time"

Solution 3 - Android

The correct path to the sdcard is

/mnt/sdcard/

but, as answered before, you shouldn't hardcode it. If you are on Android 2.1 or after, use

getExternalFilesDir(String type) 

Otherwise:

Environment.getExternalStorageDirectory()

Read carefully https://developer.android.com/guide/topics/data/data-storage.html#filesExternal

Also, you'll need to use this method or something similar

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

then check if you can access the sdcard. As said, read the official documentation.

Another option, maybe you need to use mkdirs instead of mkdir

file.mkdirs()

Creates the directory named by the trailing filename of this file, including the complete directory path required to create this directory.

Solution 4 - Android

Restart your Android device. Things started to work for me after I restarted the device.

Solution 5 - Android

If this is happening to you with Android 6 and compile target >= 23, don't forget that we are now using runtime permissions. So giving permissions in the manifest is not enough anymore.

Solution 6 - Android

use mkdirs() instead of mkdir()..it worked for me :)

File folder = new File(Environment.getExternalStorageDirectory()+"/Saved CGPA");
if(!folder.exists()){
	if(folder.mkdirs())
	Toast.makeText(this, "New Folder Created", Toast.LENGTH_SHORT).show();
}
			
File sdCardFile = new File(Environment.getExternalStorageDirectory()+"/Saved CGPA/cgpa.html");

Solution 7 - Android

in android api >= 23

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

instead of

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

Solution 8 - Android

Do you have the right permissions to write to SD card in your manifest ? Look for WRITE_EXTERNAL_STORAGE at http://developer.android.com/reference/android/Manifest.permission.html

Solution 9 - Android

Isn't it already created ? Mkdir returns false if the folder already exists too mkdir

Solution 10 - Android

There are Many Things You Need to worry about 1.If you are using Android Bellow Marshmallow then you have to set permesions in Manifest File.

  1. If you are using later Version of Android means from Marshmallow to Oreo now Either you have to go to the App Info and Set there manually App permission for Storage. if you want to Set it at Run Time you can do that by below code

    public boolean isStoragePermissionGranted() { if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { Log.v(TAG,"Permission is granted"); return true; } else {

         Log.v(TAG,"Permission is revoked");
         ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
         return false;
     }
    

    } else { //permission is automatically granted on sdk<23 upon installation Log.v(TAG,"Permission is granted"); return true; } }

Solution 11 - Android

I made the mistake of including both:

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

and:

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

in the above order. So when I took out the second permission, (READ), the problem went away.

Solution 12 - Android

File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
        + "/FoderName");
if (!f.exists()) {
	f.mkdirs();
}

Solution 13 - Android

If the error happens with Android 6.0 and API >=23 ; Giving permission in the AndroidManifest.xml is not alone enough.

You have to give runtime permissions, you can refer more here Runtime Permission

                       (or)

Google has a new feature on Android Q: filtered view for external storage. A quick fix for that is to add this code in the AndroidManifest.xml file:

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

    <!-- This attribute is "false" by default on apps targeting Android Q. -->
    <application android:requestLegacyExternalStorage="true">
     ...
     ...
    </application>
</manifest>

You can read more about it here: https://developer.android.com/training/data-storage/compatibility


Internal Storage vs Seconday Storage

The internal storage is referred to as "external storage" in the API ; not the "secondary storage"

Environment.getExternalStorageDirectory();

As mentioned in the Environment Documentation

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsajjooView Question on Stackoverflow
Solution 1 - AndroidGopinathView Answer on Stackoverflow
Solution 2 - AndroidDiiiiiiView Answer on Stackoverflow
Solution 3 - AndroidMaraguesView Answer on Stackoverflow
Solution 4 - AndroidUriel FrankelView Answer on Stackoverflow
Solution 5 - AndroidKunoView Answer on Stackoverflow
Solution 6 - AndroidBala VishnuView Answer on Stackoverflow
Solution 7 - AndroidVahe GharibyanView Answer on Stackoverflow
Solution 8 - AndroidMatthieuView Answer on Stackoverflow
Solution 9 - AndroidfedjView Answer on Stackoverflow
Solution 10 - AndroidNadeem BhatView Answer on Stackoverflow
Solution 11 - Androiduser2638345View Answer on Stackoverflow
Solution 12 - Androidashvin sapariyaView Answer on Stackoverflow
Solution 13 - AndroidSaravananView Answer on Stackoverflow