问题
I am trying to create an external directory structure to move some files from Device storage to SD card in Android phones. I have followed the steps given in https://developer.android.com/training/permissions/requesting.html and multiple stackoverflow answers. However, my program fails when I try to create the directories.
My AndroidManifest.xml
file contains the following lines:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The relevant code is as follows:
public int mkFolder(String folderName){
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
Log.d(TAG, "Error: external storage is unavailable");
return 0;
}
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d(TAG, "Error: external storage is read only.");
return 0;
}
Log.d(TAG, "External storage is not read only or unavailable");
boolean writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
boolean readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
final boolean permissionNotGranted = writePermission|| readPermission;
if (permissionNotGranted) {
Log.i(TAG, "STORAGE permissions NOT granted");
// Should we show an explanation?
boolean shouldShowRationaleForWritePermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean shouldShowRationaleForReadPermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (shouldShowRationaleForWritePermssion || shouldShowRationaleForReadPermssion) {
// Show an explanation 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 {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
} else {
Log.i(TAG, "STORAGE permissions granted");
}
// File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
File folder = new File(folderName);
int result = 0;
if (folder.exists()) {
Log.d(TAG,"folder exist:"+folder.toString());
result = 2; // folder exist
}else{
try {
if (folder.mkdirs()) {
Log.d(TAG, "folder created:" + folder.toString());
result = 0; // folder created
} else {
Log.d(TAG, "create folder fails:" + folder.toString());
result = 1; // create folder fails
}
}catch (Exception ecp){
ecp.printStackTrace();
}
}
return result;
}
public static final int REQUEST_EXTERNAL_STORAGE = 112;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
Log.e(TAG, "onRequestPermissionsResult invoked");
switch (requestCode) {
case REQUEST_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.
Log.i(TAG, "Permission to write to external storage granted");
Toast.makeText(this, "Permission to write to external storage granted", Toast.LENGTH_LONG).show();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.e(TAG, "Permission to write to external storage NOT granted");
Toast.makeText(this, "Permission to write to external storage NOT granted", Toast.LENGTH_LONG).show();
}
}
// other 'case' lines to check for other
// permissions this app might request
}
}
Here is an extract from the logs:
MainActivity: /storage/0000-0000 false true
MainActivity: /storage/0000-0000/MyDir does not exist. Creating target parent directory
MainActivity: STORAGE permissions granted
MainActivity: Creation of directory /storage/0000-0000/MyDir failed with return value 1. Aborting...
Can someone please help me understand what the mistake is in my code?
回答1:
You do not have direct filesystem access to arbitrary locations on removable storage, starting with Android 4.4. WRITE_EXTERNAL_STORAGE
is meaningless here, as external storage is not removable storage.
Use the Storage Access Framework (ACTION_OPEN_DOCUMENT_TREE
and kin) instead. Or, limit your work to the removable storage locations returned as part of getExternalFilesDirs()
, getExternalCacheDirs()
, and getExternalMediaDirs()
(all methods on Context
).
来源:https://stackoverflow.com/questions/45847179/android-6-0-sd-card-directory-creation-fails-in-spite-of-having-permissions