Built-in Camera, using the extra MediaStore.EXTRA_OUTPUT stores pictures twice (in my folder, and in the default)
Solution 1
Another way, tested on android 2.1, is take the ID or Absolute path of the gallery last image, then you can delete the duplicated image.
It can be done like that:
/**
* Gets the last image id from the media store
* @return
*/
private int getLastImageId(){
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
if(imageCursor.moveToFirst()){
int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
Log.d(TAG, "getLastImageId::id " + id);
Log.d(TAG, "getLastImageId::path " + fullPath);
imageCursor.close();
return id;
}else{
return 0;
}
}
And to remove the file:
private void removeImage(int id) {
ContentResolver cr = getContentResolver();
cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );
}
This code was based on the post: Deleting a gallery image after camera intent photo taken
Solution 2
While the answer from "Ilango J" provides the basic idea.. I thought I'd actually write in how I actually did it. The temporary file path that we were setting in intent.putExtra() should be avoided as it's a non standard way across different hardwares. On HTC Desire (Android 2.2) it did not work, And i've heard it works on other phones. It's best to have a neutral approach which works every where.
Please note that this solution (using the Intent) requires that the phone's SD Card is available and is not mounted onto the PC. Even the normal Camera app wouldn't work when the SD Card is connected to the PC.
1) Initiate the Camera Capture intent. Note, I disabled temporary file writes (non-standard across different hardware)
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(camera , 0);
2) Handle callback and retrieve the captured picture path from the Uri object and pass it to step#3
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CAPTURE_PIC: {
if (resultCode == RESULT_OK && data != null) {
Uri capturedImageUri = data.getData();
String capturedPicFilePath = getRealPathFromURI(capturedImageUri);
writeImageData(capturedImageUri, capturedPicFilePath);
break;
}
}
}
}
public String getRealPathFromURI(Uri contentUri) {
String[] projx = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, projx, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
3) Clone and delete the file. See that I used the Uri's InputStream to read the content.
The same can be read from the File of the capturedPicFilePath
too.
public void writeImageData(Uri capturedPictureUri, String capturedPicFilePath) {
// Here's where the new file will be written
String newCapturedFileAbsolutePath = "something" + JPG;
// Here's how to get FileInputStream Directly.
try {
InputStream fileInputStream = getContentResolver().openInputStream(capturedPictureUri);
cloneFile(fileInputStream, newCapturedFileAbsolutePath);
} catch (FileNotFoundException e) {
// suppress and log that the image write has failed.
}
// Delete original file from Android's Gallery
File capturedFile = new File(capturedPicFilePath);
boolean isCapturedCameraGalleryFileDeleted = capturedFile.delete();
}
public static void cloneFile(InputStream currentFileInputStream, String newPath) {
FileOutputStream newFileStream = null;
try {
newFileStream = new FileOutputStream(newPath);
byte[] bytesArray = new byte[1024];
int length;
while ((length = currentFileInputStream.read(bytesArray)) > 0) {
newFileStream.write(bytesArray, 0, length);
}
newFileStream.flush();
} catch (Exception e) {
Log.e("Prog", "Exception while copying file " + currentFileInputStream + " to "
+ newPath, e);
} finally {
try {
if (currentFileInputStream != null) {
currentFileInputStream.close();
}
if (newFileStream != null) {
newFileStream.close();
}
} catch (IOException e) {
// Suppress file stream close
Log.e("Prog", "Exception occured while closing filestream ", e);
}
}
}
Related videos on Youtube
darksider
Updated on July 31, 2020Comments
-
darksider almost 4 years
I'm currently developing an app which uses the built-in Camera. I call this snippet by clicking a button :
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String path = Environment.getExternalStorageDirectory().getAbsolutePath(); path += "/myFolder/myPicture.jpg"; File file = new File( path ); //file.mkdirs(); Uri outputFileUri = Uri.fromFile( file ); //String absoluteOutputFileUri = file.getAbsolutePath(); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(intent, 0);
After taking the picture with the camera, the jpg is well stored in sdcard/myFolder/myPicture.jpg, but it is also stored in /sdcard/DCIM/Camera/2011-06-14 10.36.10.jpg, which is the default path.
Is there a way to prevent the built-in Camera to store the picture in the default folder?
Edit : I think I will use the Camera class directly
-
RajeshVijayakumar almost 11 yearskeep it up........thnks
-
-
Swaroop almost 13 yearsHow is this different from the source given above. After all the constant
MediaStore.EXTRA_OUTPUT
resolves to String"output"
too -
ilango j almost 13 yearsdo one thing after captured image delete myPicture.jpg image. using file.delete() function.
-
Somatik over 12 yearsactivity result data is null on my android galaxy S II
-
Swaroop over 12 yearsYes, there is a problem with Samsung Manufactured phones. I'll post the approach as soon as I find a workaround. I just ordered a couple of Nexus S phones which have the Samsung Camera Issue too.. Google it.. Others are facing the issue too.
-
Alex over 12 yearsThis works but when picture is taken metadata is registered with MediaStorage so when you go to browse Gallery the thumb for then picture still going to be there even though file is gone. How do you remove that?
-
Alex over 12 yearsSorry I should add that this is on Desire 2.2
-
Ashish Mishra about 11 yearsits working good.but in my case it delete images from SD card folder.I am using Sony Ericsson phone.In my app I capture images and save to SD card folder and back to the activity where i added grid view which get the images from sd card and add to the grid view.your code working good but it delete from my folder.any help will be appreciable.
-
Derzu about 11 years@AshishMishra I'm not sure if I understand you right. If you don't wanna to dele just don't call removeImage.
-
Admin over 10 years@Derzu Don't you think it will delete wrong images in which the duplicate images are not created
-
Derzu over 10 years@FatalError Yes... there is this risk, if the new image is not really saved.
-
Admin over 10 years@Derzu is there any process to know which device creates the duplicate images and which doesn't
-
Derzu over 10 years@user2730944, I don't know how to be sure that the duplicated image was created. But the image name has the date and hour. You can try to parse this info, and see if it is near to the actual time.
-
ashishduh about 10 yearsThis is the right idea but to make it work on all devices you should first store off the most recent
MediaStore.Images.Media._ID
before calling the capture intent. Then delete any file that has a higher ID when the intent returns. See this answer -
kos over 5 yearsThis is not a good solution. The last taken image could easily be a different image than what you intend to delete.