Reputation: 171
I'm having a problem for a few days now and I can't find the solution. I've been looking on the internet for hours but I can't find any answer that works for me.
I'm making an app where I have to send pictures to a webservice. I'm using Fishbun to access to the phone gallery and pick some pictures. When the pictures are picked, I use Bitmapfactory.decodeFile()
with the returned path from Fishbun to display the pictures on the screen. It works good. The path at this moment is:
/storage/emulated/0/DCIM/Camera/IMG_20160321_044346.jpg
Then, I save the path in a ArrayList which will be send to the webservice.
When I use BitmapFactory.decodeFile()
on the path from the ArrayList, it returns null. The path is exactly the same as the first time, but it seems like I can't decode it twice.
If I restart the app and take back the same picture as the first time in fishbun, the decodeFile()
also returns null. Here is the code ....
Fishbun activity result:
protected void onActivityResult(int requestCode, int resultCode,
Intent imageData) {
super.onActivityResult(requestCode, resultCode, imageData);
switch (requestCode) {
case Define.ALBUM_REQUEST_CODE:
if (resultCode == RESULT_OK) {
path = imageData.getStringArrayListExtra(Define.INTENT_PATH);
int i = 0;
int error=0;
while(i<path.size()){
Bitmap bmp = BitmapFactory.decodeFile(path.get(i));
if(bmp.getWidth()<bmp.getHeight()) // bmp is not null the first time, null the second time
{
error++;
path.remove(i);
i--;
}
i++;
}
if(error>=1){
Toast.makeText(newStep7.this,R.string.rerrors, Toast.LENGTH_LONG).show();
}
if(path.size()>0) {
mainAdapter.changePath(path); //display the picture on the screen without changing the path, the method name is kinda wrong
}
break;
}
}
}
This is the decodeFile()
before sending my request:
String imgPath = rep.getImgList().get(0);
File file = new File(imgPath);
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
Log.d("startedfromthebottom", file.getAbsolutePath()); //show the same path as in the activityresult above
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); //bitmap is always null
bitmap.compress(Bitmap.CompressFormat.JPEG,100,os);
Could you help me find why my bitmap is null when I decode the same file twice ?
EDIT: I found the image file in my Android Device Monitor. The image size is 0 and can't be used anymore after the Outputstream
UPDATE: Little code change after applying bwt answer:
String imgPath = rep.getImgList().get(0);
File file = new File(imgPath);
AtomicFile atomicFile =
new AtomicFile(file);
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = atomicFile.startWrite();
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
Log.d("showmethebitmap", bitmap.toString()); //Error: bitmap is null !
oos = new ObjectOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.JPEG,0,oos);
oos.writeObject(bitmap);
oos.flush();
atomicFile.finishWrite(fos);
...
} catch (IOException e) {
atomicFile.failWrite(fos);
throw e;
} finally {
if (oos != null) oos.close();
}
Upvotes: 2
Views: 8819
Reputation: 1154
I know the question has been answered ,however if someone still getting null make sure that the application has permission to read user's files
Upvotes: 2
Reputation: 17725
You should load the image first, then open the output stream, as this erases the existing content.
Log.d("startedfromthebottom", file.getAbsolutePath()); //show the same path as in the activityresult above
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); //bitmap is always null
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG,100,os);
This is a bit dangerous because if something goes wrong the image is lost. It could be a good idea to use an AtomicFile.
Edit (based on your updated code) :
String imgPath = rep.getImgList().get(0);
File file = new File(imgPath);
AtomicFile atomicFile = new AtomicFile(file);
FileOutputStream fos = null;
try {
// read the current image
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
// open the stream (backup the current content)
// from now on (and until finishWrite/failWrite) we cannot read the file directly
fos = atomicFile.startWrite();
Log.d("showmethebitmap", bitmap.toString()); //Error: bitmap is null !
OutputStream oos = new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.JPEG,0,oos);
// flush but do not close the stream (@see AtomicFile doc)
oos.flush();
// close the stream, remove the backup
atomicFile.finishWrite(fos);
...
} catch (IOException e) {
// recover the content from the backup
atomicFile.failWrite(fos);
throw e;
}
Upvotes: 0