Creating a directory in /sdcard fails
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"
There are three things to consider here:
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();
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"/>
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 }
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.
Restart your Android device. Things started to work for me after I restarted the device.