问题
A little bit of background first: this app takes a picture and uploads to an Azure blob storage.
The picture is stored in a file (internal storage) using getApplicationContext().getFilesDir();
To upload, I need to call the uploadFromFile(..) function like so:
CloudBlockBlob.uploadFromFile(String path);
The Azure SDK's uploadFromFile function looks like this:
public void uploadFromFile(final String path) throws StorageException, IOException {
uploadFromFile(path, null /* accessCondition */, null /* options */, null /* opContext */);
}
public void uploadFromFile(final String path, final AccessCondition accessCondition, BlobRequestOptions options,
OperationContext opContext) throws StorageException, IOException {
File file = new File(path);
long fileLength = file.length();
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
this.upload(inputStream, fileLength, accessCondition, options, opContext);
inputStream.close();
}
The issue is on the line long fileLength = file.length(); where the fileLength is 0.
I have tested this against using Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); for the storage directory. This works.
I need to use the internal storage vs external storage since that is specifically required for this project.
EDIT: The Android File documentation mentions nothing about this behavior. I am assuming this might be something to do with using the app internal storage.
EDIT: Adding some code
I am sending a File mPhotoFile to my Camera intent. This will contain the photo. mPhotoFileUri contains the URI for this file. Following is the code to use the path from the file.
File file = new File(mPhotoFile.getPath()); // value -> /data/user/0/com.example.devpactapp/files/JPEG_20160209_234929_1936823724.jpg
boolean fileExists = file.exists(); // true
long fileLength = file.length(); // length 0
Following is the code to get the file from the URI.
File file = new File(mPhotoFileUri.getPath()); // value -> /data/user/0/com.example.devpactapp/files/JPEG_20160209_235534_-1059496729.jpg
boolean fileExists = file.exists(); // true
long fileLength = file.length(); // length 0
I have to pass the path of this file to the uploadFromFile function.
Workaround mentioned in my 'answer'.
回答1:
Even though I don't have all the information, I'm gonna make the call that the file is missing from the path you've given. The javadoc for length() specifically mentions this case will return 0.
So try checking exists() before you do anything with the file.
回答2:
While using internal storage the file path is different. I think it is stored in /storage/emulated in latest devices. Check for your file path. and see if you are creating a file with the absolute path.
回答3:
Found a workaround. This is the function I was using to get the file that was being passed to the Camera intent.
// Create a File object for storing the photo
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getApplicationContext().getFilesDir();
mPhotoFileExists = true;
// check if access to external storage exists
// if returned true, return the new file
// if returned false, user could have been requested for access
// so, need to check if permission is available now
// if still not available, return null
if(haveWritePermissions())
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return null;
}
I changed the storageDir from getApplicationContext().getFilesDir(); to getApplicationContext.getExternalFilesDir(null);
Docs: getExternalFilesDir(String type), getFilesDir()
I passed null since I didn't want to put Environment.DIRECTORY_PICTURES, which would allow the Media Scanner to find the image file.
I understand that this, in no way, is a 'fix'. Still looking for an answer as to why getFilesDir() is causing this issue.
EDIT: Very pressing reason as to why this is not a good solution - external storage may not always be available, and there would not be any workaround in that case. Also, any other app with permission WRITE_EXTERNAL_STORAGE can write here. So, no security is enforced either.
来源:https://stackoverflow.com/questions/35306866/file-length-is-0-when-recreating-file-from-uri-or-original-filepath-getexterna