Android App create directory works for most but gives error unable to create directory on sdcard on many
My application creates a directory name on the phone's sd card and stores a bunch of images in it. The code works fine for the majority of users, but some are reporting errors saving files.
Here is the code that creates the directory: R.string.dir is set to "/appname/"
dir = Environment.getExternalStorageDirectory() + ((String) getResources().getText(R.string.dir));
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
File fDir = new File(dir);
fDir.mkdirs();
}
else{
showToast(false,"This Application needs a mounted external storage (sdcard).");
finish();
}
So at this point the directory should be created (it ends up being /mnt/sdcard/appname), or the app finishes.
However when attempting to save the file, some users are reporting this exception:
Msg: java.io.FileNotFoundException: /mnt/sdcard/appname/file.jpg (No such file or directory)
The code that does the saving:
File file = new File("/mnt/sdcard/appname/file.jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream( file );
b.compress(Bitmap.CompressFormat.JPEG, 100, fos );
}
catch( Exception e ) {
Any suggestions? Could it be that mkdirs() return false (well it would do that if the directory is already created, but then i should be able to write the file in there)? What would be another reason for it to return false if the sdcard is mounted? How can I handle this better?
Yes we are using unique file names (appending System.currentTimeMillis() to the filename). Also the stream is closed at the end
开发者_运维技巧 finally
{
if(fos != null) {
try {
fos.close();
}
catch(Exception ex){
ex.printStackTrace();
}
}
You assume (in the second code sample) that the sdcard paths in all devices is /mnt/sdcard/
. This is a wrong assumption. you should call Environment.getExternalStorageDirectory to get the correct path.
Also, maybe the directory there but not the file, add the following code before opening output stream:
if (!file.exists()) {
file.createNewFile();
}
To summarize the direction that the other posts are going here are some potential problems
- The names are not the same in first and second method (Or they might be, dont know)
- Since you are hard coding a name the file might already exist
- You are not closing the stream
- You said the string in the resource was set to /appname/ hopefully you mean your applications name, a lot of people might be using the literal appname and file.jpg to store things since that shows up in a lot of tutorials etc.
Modified to take those into account it maybe should look more like this
String sdCard = Environment.getExternalStorageDirectory() + ((String) getResources().getText(R.string.dir));
File file = new File(sdCard + "/appname/file.jpg"); // DO YOU WANT YOUR APP NAME OR JUST APPNAME ???
if (file.exists()) // if the jpg already exists --- problems
file.delete();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file.getPath());
b.compress(Bitmap.CompressFormat.JPEG, 100, fos );
fos.close();
}
catch( Exception e ) { ... }
Outside of this there can be other potential problems. If the user has the device hooked up to a USB and set as a hard drive the sdcard my not be reachable, the sdcard might be read only, the user might not have an sdcard (which you are checking so cross that one out)
精彩评论