47

I'm driven crazy with this:

Log.d("STATE", Environment.getExternalStorageState());
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "work_data");
Log.d("PATH", f.getAbsolutePath());
if (!f.exists()) {
    Log.d("MAKE DIR", f.mkdirs() + "");
}

The output log looks like this:

STATE     mounted
PATH      /mnt/sdcard/DCIM/work_data
MAKE DIR  false

I made sure to add the correct permission:

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

But I don't know why it could not create the folder. I also used mkdir() step by step but the result is the same. Please help me. I have googled so much and spent at least 2 days on this stupid thing. Thanks for your help!!

EDITING:

Sorry everyone! I had added <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> in <application> tag. this was my mistake! But thank you all for reply.

Chris
  • 5,876
  • 3
  • 43
  • 69
MHM
  • 854
  • 1
  • 9
  • 17
  • Your question allowed me to a solve my own problem with mkdirs() (I was missing the WRITE_EXTERNAL_STORAGE authorization). The reason was not obvious because of the absence of "permission denied" exception thrown... – Sébastien Jan 22 '12 at 10:13
  • Yes, with you on the crazieness. The way android have overcomplicated the simple task of creating folders and files is crazy. – Paul McCarthy Dec 10 '22 at 18:25

16 Answers16

64

I got the same problem,and I am sure I had put the permission tag in the right place,but mkdirs didn't work yet, my system is Android 6.0, I resolve it now , you can check as below:

  1. make sure your put the permission tag in .
  2. open "setting/application" in your phone,check your application's permission(I found the permission in my manifest statement is not here),open the switch of the permission like this.(I found it is closed in default which make "mkdirs" failed)

enter image description here

Jiakang Zhang
  • 869
  • 1
  • 7
  • 6
  • 9
    In Android 6.0, you request certain permissions when you use them. You can make the request using the function `ActivityCompat.requestPermissions`. See [here](https://developer.android.com/training/permissions/requesting.html) for more information. – Chris Aug 27 '16 at 04:03
  • 1
    In my case I was asking for permissions in the manifest, but somehow it was disabled in App permissions. You saved my life, I love youu! ❤❤❤ – claudevandort Jan 24 '19 at 18:55
  • 1
    For some reason, I just had to toggle this permission off then on again and it worked. – Randy Sep 04 '19 at 21:25
34

I have had the same problem and I have searched everything for a week trying to find the answer. I think I found it and I think it's ridiculously easy, you have to put the uses-permission statement in the right place...

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.name" 
    android:versionCode="1"
    android:versionName="0.2">

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

When I had it inside the <application></application> section it did not work.

Pang
  • 9,564
  • 146
  • 81
  • 122
Omnivore
  • 414
  • 4
  • 7
16

I know this is an old post but perhaps my answer can help somebody.

After several days dealing with this problem I have realized that while the phone is connected to the PC, which it turns to be always during development, the SD card is not available. Thus making to fail any attempt to create a directory or file over it. To make it "easier" it seemed to behave differently depending of the telephone under test.

I know it can sound quite a silly problem, but it cost a lot of time that maybe some other can save.

Clark Ku
  • 491
  • 2
  • 7
  • 10
16

Applicable only if your targetSdkVersion is 29 or above

Environment.getExternalStorageDirectory() is deprecated in API level 29.

To get the same functionality use this line

File mediaStorageDir = context.getExternalFilesDir(null);

If you have checked all the possible errors then try this fix.

Already answered here - https://stackoverflow.com/a/61480077/7764015

Priyankchoudhary
  • 786
  • 9
  • 12
  • 1
    Bless your heart! Not sure how I missed this or why Android Studio didn't forcibly warn me that was deprecated. Seems like a big deal to remove that. – KisnardOnline Sep 03 '20 at 02:54
  • 1
    For targetSdkVersion 29, there may be some differences. getExternalFilesDir(null) is the directory of the app which is created in .../Android/data/ with app-package-name. If someone's old app created some directory in other place, such like in root. This answer cannot cover the issue because they are two different directories. A temporary solution should be this: developer.android.com/training/data-storage/… – Fisher Sep 19 '20 at 16:03
  • This one fixed my issue too,, I am using targetSdkVersion greater than 29 – Kalyan Pradhan Mar 24 '21 at 07:10
  • getExternalFilesDir will only return access to the app's own private data on the external storage. These files/folders are not accessible to other apps. – Johann Dec 14 '21 at 14:48
13

add this line of code in OnCreate()

ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
Osama Ibrahim
  • 995
  • 10
  • 13
  • 2
    I have the correct permission in `Manifest` file, and it works fine on android 7.1, but tried on android 9.0 not working, `requestPermission` did the trick, thx!! – Sam Jan 16 '19 at 17:04
  • 2
    This sorted my issue with API 26+ – alex_z Jan 23 '19 at 13:39
10

Might be it's too late for answer but if you already allowed R/W permission(Runtime Permission too) and still doesn't work add this below mentioned line in your AndroidManifest.xml

<application
........
........
android:requestLegacyExternalStorage="true">

Note: this must required if you'r targeting Android 10+

Bhavesh Moradiya
  • 1,323
  • 14
  • 18
6

mkdirs() only returns true if the directory was created. If it is in place already, it should return false. So I would bet this directory already exists.

dragonroot
  • 5,653
  • 3
  • 38
  • 63
4
<application
        .....
        android:requestLegacyExternalStorage="true">

work well.

simpman
  • 41
  • 1
3

I had the same issue, and I just wanted to share my fix. as per android Beginning with Android 4.4, reading or writing files in your app's private directories does not require the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions.

So you can declare the permission should be requested only on the lower versions of Android by adding the maxSdkVersion attribute:

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

but maxSdkVersion is the issue, I just removed it and now it works.

Manish Jain
  • 842
  • 1
  • 11
  • 29
2

If you have android 6.0 and more, make sure your target sdk in gradle file less than 22:

targetSdkVersion 22

or you need to implement run time permissions.

phnmnn
  • 12,813
  • 11
  • 47
  • 64
2

put this

Log.d("MAKE DIR", f.mkdir() + "");

instead of

Log.d("MAKE DIR", f.mkdirs() + "");

or try this

String s=Environment.getExternalStorageDirectory().toString()+"/";
File f = new File(s+"DCIM/work_data");
Mohammed Azharuddin Shaikh
  • 41,633
  • 14
  • 96
  • 115
2

Your code is working fine for me.There is no any thing wrong in your code. Just if you are making one directory use f.mkdir() instead of f.mkdirs() You can see your folder in mnt => Sd card => DCIM => work_data

Dharmendra
  • 33,296
  • 22
  • 86
  • 129
  • I checked `f.mkdir()` too but there is no difference. I also check in files System and there is not such folder!!! – MHM Aug 27 '11 at 08:15
  • I had just copy and paste your code in my activity and it is working it is creating folder.I don't know why you are getting problem. – Dharmendra Aug 27 '11 at 08:54
1

This might help someone in the future.

the problem might also be that you write the address "/File/Address/" instead you should write

File.separator + "File" + File.separator + "Address" + File.separator

This is such a small and stupid thing but this worked for me after wasting hours of my time.

Mayank
  • 1,364
  • 1
  • 15
  • 29
1

If you're targeting Android api 29 then add this in your AndroidManifest.xml

<application android:requestLegacyExternalStorage="true">

0

I tried to make a set of subfolders in external storage 'Test/Test1/Test2' when mkdirs() kept returning false. Turns out that 'Test' is either a reserved word for a folder in the external storage root. This was on a Motorola G (XT1541) and may apply to other devices as well.

0

For new devices, you have to ask user permission.

You can do that like this before create your file:

            boolean hasPermission = (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
        if (!hasPermission) {
            //ask permission
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_WRITE_STORAGE);
        }
        else {

           //you have permission, create your file
        }

After user's action, you can handle result.

  @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case 1: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //you have permission, create your file
                //reload my activity with permission granted or use the features what required the permission
            } else
            {
                Toast.makeText(MainActivity.this, "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();
            }
        }
    }

}