I'm launching the camera from my app to take a photo. It also becomes available in the gallery.
The common issue with this, is how to know the path of the photo. The proposed solutions are:
save the path yourself, and send it over using EXTRA_OUTPUT
take the path from the last taken photo in the gallery.
Solution 1 isn't reliable.
I'm trying to make solution 2 work, with this code:
public static String getTakenPhotoPath(Context context) {
try {
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, null, null, null);
int column_index_data = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();
return cursor.getString(column_index_data);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
This doesn't return the path of the latest photo; it returns the previous one. Before asking for the path of the latest photo, I'm doing this:
private void addToGallery(Uri urlType, String path) {
if (!Strings.isNullOrEmpty(path)) {
ContentValues values = new ContentValues();
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.MediaColumns.DATA, path);
getContentResolver().insert(urlType, values);
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(new File(path));
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
}
You can it do like this: When you are opening the camera, you can pass your own preferred location for future captured image like this in given code. And in onActivityResult you can directly use that image path for your use.
File image ;
Intent photoCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages");
imagesFolder.mkdirs(); // <----
image = new File(imagesFolder, getFileName());
Uri uriSavedImage = Uri.fromFile(image);
photoCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(photoCaptureIntent, PICK_FROM_CAMERA);
private String getFileName() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
Date now = new Date();
String fileName = formatter.format(now) + ".jpg";
return fileName;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
setResult(resultCode, data);
switch (requestCode) {
case PICK_FROM_CAMERA:
try {
if (resultCode != RESULT_CANCELED) {
Intent upload = new Intent(EditProfile.this, ImageCropingFucAtivity.class);
prefs.edit().putBoolean("FromCamera", true).commit();
upload.putExtra(CropImage.IMAGE_PATH, image.toString());
upload.putExtra(CropImage.SCALE, true);
upload.putExtra(CropImage.ASPECT_X, 2);
upload.putExtra(CropImage.ASPECT_Y, 2);
startActivity(upload);
imageSelected = true;
finish();
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
Related
I want to save the image without compressing it and want to save it in it's original form i.e. when image is compressed the image size decreases and image become small. I am using native camera for this purpose. I am working in android studio. I am making an app in which i am using a camera to save image. But the image is compressed and is very small and very lower quality.
Below is my code for saving image
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
{
if(resultCode == Activity.RESULT_OK)
{
Bitmap bmp = (Bitmap)data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
if(isStoragePermissionGranted())
{
SaveImage(bitmap);
}
}
}else {
switch (requestCode) {
case 1000:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
getLocation();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(this, "Location Service not Enabled", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
}
private void SaveImage(Bitmap finalBitmap) {
File storageDir = new File (String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)));
String root = storageDir + Environment.getExternalStorageDirectory().getAbsolutePath().toString();
Log.v(LOG_TAG, root);
File myDir = new File(root + "/captured_images");
if (!myDir .exists())
{
myDir .mkdirs();
}
Random generator = new Random();
int n = 1000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir,fname);
try {
file.createNewFile();
MediaScannerConnection.scanFile(getApplicationContext(), new String[] {file.getPath()} , new String[]{"image/*"}, null);
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Update 1
For more understanding i am putting my onClick method
btn_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check permission for camera
if(ActivityCompat.checkSelfPermission(MainActivity.this, CAMERA)
!= PackageManager.PERMISSION_GRANTED)
{
// Check Permissions Now
// Callback onRequestPermissionsResult interceptado na Activity MainActivity
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{CAMERA},
MainActivity.REQUEST_CAMERA);
}
else {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
}
});
I searched the solution and found that i can use AndroidBitmapUtil
class so i copy and pasted this class into my project i.e. i created a new class. But i don't know how to use it. Although it is described that i can save image by doing new AndroidBmpUtil().save(bmImage, file);. But again i can't match with my code :(
Any help would be highly appreciated
new AndroidBmpUtil().save(source, sdcardBmpPath);
USER ABOVE LINE OF CODE AND FOLLOW BELOW LINK
https://github.com/ultrakain/AndroidBitmapUtil
Open Camera and save image into some specific directory.
solution number 1
private String pictureImagePath = "";
private void openBackCamera() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = timeStamp + ".jpg";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
pictureImagePath = storageDir.getAbsolutePath() + "/" + imageFileName;
File file = new File(pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, 1);}
Handle Image
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
File imgFile = new File(pictureImagePath);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
myImage.setImageBitmap(myBitmap);
}
}
solution number 2
I have used the following code and this works perfectly fine for me.
values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICTURE_RESULT);
and also
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICTURE_RESULT:
if (requestCode == PICTURE_RESULT)
if (resultCode == Activity.RESULT_OK) {
try {
thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
imgView.setImageBitmap(thumbnail);
imageurl = getRealPathFromURI(imageUri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
and
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
For opening camera use
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "imagename.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, 1);
and in your onActivityresult method use
if (requestCode == 1) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("imagename.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bitmap;
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath(),bitmapOptions);
yourimageview.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
I've got a problem trying to upload an image I get from taking a picture with the camera,using amazon S3 android library.
To save the picture
File _photoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), (cal.getTimeInMillis() + ".jpg"));
try {
if (_photoFile.exists() == false) {
_photoFile.getParentFile().mkdirs();
_photoFile.createNewFile();
}
} catch (IOException e) {
// Log.e(TAG, "Could not create file.", e);
}
// Log.i(TAG, path);
filePath = Uri.fromFile(_photoFile);
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, filePath);
startActivityForResult(cameraIntent, 1);
To upload the picture with the filePath:
try {
s3Client.createBucket(Constants.getPictureBucket());
// Content type is determined by file extension.
PutObjectRequest por = new PutObjectRequest(
Constants.getPictureBucket(), Constants.PICTURE_NAME,
new java.io.File(filePath));
s3Client.putObject(por);
} catch (Exception exception) {
result.setErrorMessage(exception.getMessage());
}
I keep getting an error Unable to calclualte MD5 hash:/file:/storage/sdcard0/DCIM/13161272646580.jpg open failed:ENOENT (No such file or directory)
but when I browse my sd card's directory I can find the picture there(the picture has been created), and I've created the relevant permissions.
The problem is in your file path. Use a method like that to get the Real Path.
I give you an example, if you are getting the image from onActivityResult()
You should have a onActivityResult(int requestCode, int resultCode, Intent data) where you can get the Uri of your image.
Uri uri = data.getData();
Then you use it and get the real path from Uri and pass this to the PutObjectRequest(BUCKET_NAME, IMAGE_NAME, REAL_PATH);
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
I had the same problem and I solve it doing this. Hope it helps!
I don't really remember what I did. But this is the code I use that works. Hope it can help you guys!
AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials("XXX", "XXX"));
String time = "" + System.currentTimeMillis();
PutObjectRequest por = new PutObjectRequest("fraternity", xyz_url_xyz + "/avatar" + time + ".jpg", new java.io.File(params[0]));
por.setCannedAcl(CannedAccessControlList.PublicRead);
s3Client.putObject(por);
ResponseHeaderOverrides override = new ResponseHeaderOverrides();
override.setContentType("image/jpeg");
GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest("xyz_url_xyz/avatar.jpg");
urlRequest.setExpiration(new Date(System.currentTimeMillis() + 3600000));
urlRequest.setResponseHeaders( override );
s3Client.generatePresignedUrl(urlRequest);
I have one problem. When I try to get picture from camera, the quality is very low.
At first, capture the picture using camera, than save to the directory and at the same time get that picture and show in my app.The picture saved inside directory is a fine quality but when I get it from directory, the quality is low. below is my sample code :
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == CAMERA_PIC_REQUEST) {
Bitmap thumbnail = (Bitmap) intent.getExtras().get("data");
if (g==1)
{
ImageView myImage = (ImageView) findViewById(R.id.img5);
myImage.setImageBitmap(thumbnail);
View a = findViewById(R.id.img5);
a.setVisibility(View.VISIBLE);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byteArray1 = stream.toByteArray();
}
}
any solution/suggestion?
Thanks :)
Solved
The problem solved when I follow the code given by Antrromet below
I have used the following code and this works perfectly fine for me.
values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "New Picture");
values.put(MediaStore.Images.Media.DESCRIPTION, "From your Camera");
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICTURE_RESULT);
and also
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICTURE_RESULT:
if (requestCode == PICTURE_RESULT)
if (resultCode == Activity.RESULT_OK) {
try {
thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
imgView.setImageBitmap(thumbnail);
imageurl = getRealPathFromURI(imageUri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
and
public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I will give you something that work for me. I asked the same !
Solution to save a picture in a specific folder without lost quality
I FOUND THE SOLUTION:
//Create a new folder code:
String path = String.valueOf(Environment.getExternalStorageDirectory()) + "/your_name_folder";
try {
File ruta_sd = new File(path);
File folder = new File(ruta_sd.getAbsolutePath(), nameFol);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
Toast.makeText(MainActivity.this, "Carpeta Creada...", Toast.LENGTH_SHORT).show();
}
} catch (Exception ex) {
Log.e("Carpetas", "Error al crear Carpeta a tarjeta SD");
}
Intent i = new Intent(MainActivity.this, MainActivity.class);
startActivity(i);
finish();//agregue este
//Method to take a Picture
public void clickFoto(View view) {
takePic();
}
//takePic()
private void takePic() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
*File file = new File(Environment.getExternalStorageDirectory(), "/your_name_folder/a" + "/photo_" + timeStamp + ".png");*
imageUri = Uri.fromFile(file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PICTURE_RESULT);
}
//onActivityResult
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICTURE_RESULT:
if (requestCode == PICTURE_RESULT)
if (resultCode == Activity.RESULT_OK) {
try {
Bitmap thumbnail = MediaStore.Images.Media.getBitmap(
getContentResolver(), imageUri);
imgFoto.setImageBitmap(thumbnail);
imageurl = getRealPathFromURI(imageUri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// getRealPathFromUri
public String getRealPathFromURI(Uri contentUri) {
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Add the photo to a gallery
.
.
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(currentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
for more detail : https://developer.android.com/training/camera/photobasics.html
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
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
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);
}
}
}
try this code:
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("output", outputFileUri);
startActivityForResult(intent, 0);
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
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
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);
}
}
}
try this code:
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("output", outputFileUri);
startActivityForResult(intent, 0);