mkdirs returns false for directory on sd card while the parent directory is writable
Asked Answered
V

14

19

When starting my android application, I need to create a directory on the sd card, for a small number of users this fails and I can't figure out the reason for it...

(I've found similar problems caused by the WRITE_EXTERNAL_STORAGE permission missing, it's there and it works for almost all users so I don't think this is reason)

I've simplified the previous situation to make it easier to explain, if creating a directoy fails, I run a test case where I try to make a .test directory on the sdcard:

new File(Environment.getExternalStorageDirectory(), ".test").mkdir() -> false
new File(Environment.getExternalStorageDirectory(), ".test").mkdirs() -> false

File properties of the relevant directories:

/sdcard/.test (exists=false canWrite=false canRead=false canExecute=err isDirectory=false isFile=false)

/sdcard (exists=true canWrite=true canRead=true canExecute=err isDirectory=true isFile=false)

/ (exists=true canWrite=false canRead=true canExecute=err isDirectory=true isFile=false)

getExternalStorageState=mounted

(canExecute returns err because the test is run on sdk < 9)

Suggestions and ideas are very welcome...

Valenta answered 31/10, 2010 at 8:25 Comment(4)
Could you show the code where you are trying to create the directory? For example, if you have hard-wired /sdcard, that might be your problem right there.Bortz
@CommonsWare: I'm using Environment.getExternalStorageDirectory() and thinking of switching to Context.getExternalFilesDir(null) once I figure this problem out... I'll edit my original post with the code.. Thansk for the fast reply!Valenta
Bear in mind that getExternalFilesDir() only exists for Android 2.2 and is broken in that release. I'd stick to your current strategy for the foreseeable future.Bortz
You found the solution ?Ben
L
15

It is common when you don't have a permission in your manifest.

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

As for me it was the only wrong thing.

Langton answered 31/10, 2010 at 10:23 Comment(1)
I only have this problem for a very small number of users and my AndroidManifest.xml has the WRITE_EXTERNAL_STORAGE permission inside the manifest tag so I'm sorry to say this is not the reason..Valenta
L
7

I had a simillar problem and spent several hours to realise what is wrong. It didn't work on Sumsung Mega, but for other phones it worked fine. I really had WRITE_EXTERNAL_STORAGE permission and getExternalStorageDirectory is mounted and available. But still the directory wasn't created. What helped ? I just restarted the divice! And it helped! It's a pity that nobody adviced this before. Hope this will help!

Landwaiter answered 29/5, 2015 at 19:23 Comment(0)
A
7

First of all, technically mkdirs() returning false doesn't mean that it failed, it just meant that it didn't make the directories. If the directories already exist then mkdirs() will continue to return false.

Secondly, in Android 6, not only do you need:

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

You also need some equivalent of:

ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED

For more info on checking permissions, see:
https://github.com/googlesamples/android-RuntimePermissions

Adalai answered 17/2, 2016 at 1:47 Comment(1)
And what to do in case permission is not granted? How to request it properly?Ixion
E
4

I have had issues trying to create directories on the SDCard as well. I found what was happening is that my code would work fine on some phones, and also the emulator. However other phones would report errors.

I believe there is an issue with certain phones, the Atrix and the Bionic are two examples.

These phones when using the Environment.getExternalStorageDirectory() code actually return /mnt/sdcard.

However on these phones the SD card is actually /mnt/sdcard-ext.

So somewhere along the lines it looks like some manufactures have broken the getExternalStorageDirectory code, and somehow its returning a false location.

I had a heck of a time figuring this out because my code worked on many different devices, and still some users reported it failed.

Egidius answered 11/10, 2011 at 18:32 Comment(0)
J
4

My problem was that I was using mkdir for creating a multiple directories path and I got false everytime. Once I used mkdirs my problem got resolved

Joselow answered 25/7, 2013 at 7:45 Comment(0)
S
3

I had the same problem. The permission was set and also the path was the default one (/mnt/sdcard) but my android was mounted as an external storage device for quick browsing the SD card. However this interferes with other apps.

I figured this out when diving into the adb shell:

$ cd /mnt   
$ cd sdcard
cd: can't cd to sdcard
$ ls -l
d--------- system   system            2011-12-07 01:59 sdcard

after unmounting the image I've got:

$ ls -l                   
drwxrwxr-x system   sdcard_rw          2011-12-07 11:46 sdcard

As you can see while mounted the sdcard is in the system user group and there are no permissions at all. After unmounting the group is changed to sdcard_rw and permissions to read and write are granted.

Soracco answered 7/12, 2011 at 10:54 Comment(0)
V
3

I know this is an old posting but I thought I can still offer a suggestion. If you're running your app while developing (ie. the phone is plugged into the PC via USB), then chances are, the SD card has been mounted by the PC. You have to unmount it (you can do it from the phone or from the PC) in order to gain write permission, this requires that has been set in the manifest.

Vociferous answered 3/1, 2012 at 11:0 Comment(0)
M
3

I thought I was having this problem while debugging an app. It was failing because the SD Card was mounted by the host computer while debugging. Unmounting from the computer made the app work again.

Madera answered 10/9, 2012 at 0:43 Comment(1)
Maybe I'm wrong but that's technically same answer as mine just with less words … :|Soracco
V
2

It is possible that these users have an SD card that is corrupt and thus mounted read-only. If possible, you should check with them to see if anything else can write files to it. Given that you have the WRITE_EXTERNAL_STORAGE permission, you should have no trouble making modifications to the SD card (and the permissions of everything in the SD card is world read/write for such apps, so nothing can mess with file permissions to cause them trouble either).

Volva answered 31/10, 2010 at 18:28 Comment(1)
I don't think this is it, I use developer.android.com/reference/android/os/… to check for this and it gives "mounted", it should give "mounted_ro" in your situation I think... Thanks though..Valenta
A
1

I ran into this problem when the symlink /storage/emulated/0 was somehow missing. What I did was use the camera app to take a picture. I observed that the pictures details said it was within /storage/emulated/0, though that directory did not exist from the file explorer. Then I rebooted the phone. After reboot the directory showed up in file explorer.

Anonymous answered 9/9, 2014 at 23:47 Comment(0)
P
1

I was having a similar problem. My camera app was working fine in all the android versions but Q (10).

The issue was that I using Environment.getExternalStorageDirectory(); and its deprecated in android Q (onwards). The solution was simple, using something that was supported in the latest version which will be context.getExternalFilesDir()

Here is how I get it working in all the devices:-

public static boolean createDirectory(Context context, String directoryPath) {
    File folder;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
        folder = new File(context.getExternalFilesDir(null), directoryPath);
    else
        folder = new File(Environment.getExternalStorageState(), directoryPath);

    if (!folder.exists()) {
        return folder.mkdirs();
    }

    return true;
}
Palaeontology answered 11/4, 2020 at 12:23 Comment(0)
N
1

This can also happen if you target SDK 29 or greater(targetSdkVersion in build.gradle) due to the introduction of scoped storage. If that is the case, either change your target SDK to 28 or lower or add: android:requestLegacyExternalStorage="true" to your manifest, under Application key.

Newel answered 9/9, 2020 at 18:12 Comment(0)
P
0

I experienced a similar problem when using mkdirs(), however because running the command:

mkdir one/two

fails on Linux, then the API (http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#mkdirs()) subsequently fails too. I guess this means there is no way to use mkdirs on Android? My (probably rather hacky) work-around was to create each necessary directory separately:

String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
new File(extStorageDirectory + "/one/").mkdirs();
new File(extStorageDirectory + "/one/two/).mkdirs();
Patent answered 8/4, 2011 at 13:17 Comment(0)
D
0

I ran into this issue on virtual device. For me the issue was that I had defined no external storage for the virtual device. Hopefully helps someone.

Dannielledannon answered 18/9, 2014 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.