问题
I'm trying to write a photo on the SD card without success.
I've got the permissions to write in the removable storage and the sd card is mounted.
Also, I checked that the path to the SD card exists and I have obtained a positive result.
Where it fails is when I use the mkdir() function. It returns false and no file is created.
I have tested on both a Samsung A6(Marshmallow) and a Samsung Tab4(Lollipop)
This is the snippet of code I'm using to retrieve the path to the SD-card.
Because the standard procedure didn't work with Samsung devices, I'm using this snippet of code that I took from a stackoverflow answer
The path returned with this function from the Samsung A6 is /storage/6DD9-1D15.
public String[] getStorageDirectories() {
String[] storageDirectories;
String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
List<String> results = new ArrayList<String>();
File[] externalDirs = getApplicationContext().getExternalFilesDirs(null);
for (File file : externalDirs) {
String path = file.getPath().split("/Android")[0];
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Environment.isExternalStorageRemovable(file))
|| rawSecondaryStoragesStr != null && rawSecondaryStoragesStr.contains(path)) {
results.add(path);
}
}
storageDirectories = results.toArray(new String[0]);
} else {
final Set<String> rv = new HashSet<String>();
if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
storageDirectories = rv.toArray(new String[rv.size()]);
}
return storageDirectories;
}
This, instead, is the code I'm using to write a folder in the DCMI Directory under the SD-card(in which I will put the photos)
public void mkFolder(String folderPath) { // make a folder under Environment.DIRECTORY_DCIM
File folder = new File(folderPath);
try {
// MKDIRS returns false
if (folder.mkdirs()) {
Log.d(TAG, "folder created:" + folder.toString());
} else {
Log.d(TAG, "create folder fails:" + folder.toString());
}
} catch (Exception ecp) {
ecp.printStackTrace();
}
}
回答1:
On API Level 18 and below, your getStorageDirectories() will go through its else block. That block assumes:
- that the
SECONDARY_STORAGEenvironment variable exists... which is not required - that the
SECONDARY_STORAGEcontains a delimited list of directories... which is not required - that the list of directories matches removable storage options... which is not required
- that you can work with those directories... which is not required
On API Level 19+, your getStorageDirectories() code will go through its if block. There, you start off fine, calling getExternalFilesDirs(). If that method returns 2+ items, the second and subsequent ones point to removable storage, and specifically point to places on removable storage where you can read and write. Then, your code assumes:
- that the directory has an
/Androidpath segment... which is not required - that the portion of the directory path preceding
/Androidrepresents a location in which you can create files and directories... which is never true
You do not have filesystem-level access to removable storage, except in the specific directories returned by methods like getExternalFilesDirs().
So, either:
Stick to the specific locations returned by
getExternalFilesDirs(), orSwitch to using the Storage Access Framework, allowing the user to choose where to store content (which may or may not be removable storage)
来源:https://stackoverflow.com/questions/42332978/cant-write-file-on-sd-card