I have a working piece of code that uses a camera to take a picture. When the picture has been taken, I am receiving it to scale it down and manipulate it in different ways. What I want to do is deleting the original saved picture (done automatically by Android) and save my manipulated picture afterwards.
So here is my code for starting the intent:
private void takePicture(){
File storagePath = getAlbumStorageDir();
String timeStamp = System.currentTimeMillis()+"";
File file = new File(storagePath, timeStamp + ".jpg");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
file.delete();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
capturedImageUri = Uri.fromFile(file);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
context.startActivityForResult(i, CameraCapture.REQUEST_TAKE_PHOTO);
}
private File getAlbumStorageDir() {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), context.getResources().getString(R.string.gallery));
Log.d("PICTUREVIEW", file.getAbsolutePath());
if (!file.mkdirs()) {
Log.e("MyFileStorage", "Directory not created");
}
return file;
}
And when it is returned, I am handling it like this:
private void manageCapturedPicture() {
try {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(capturedImageUri);
context.sendBroadcast(mediaScanIntent);
//loadPictures();
Bitmap bm = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(capturedImageUri));
int width = LayoutUtil.getScreenWidth(context) * 2;
if (width > 600) {
width = 600;
}
double ratio = ((double)bm.getHeight() / (double)bm.getWidth());
double height = width * ratio;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bm, width, (int)height, true);
ContentResolver contentResolver = context.getContentResolver();
contentResolver.delete(capturedImageUri, null, null);
imageView.setImageBitmap(scaledBitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
As you can see, I am scaling down the image and showing it in an imageview (simply for testing purposes). This was working fine until I attempted to delete the original picture from the external storage. When I added these to lines:
ContentResolver contentResolver = context.getContentResolver();
contentResolver.delete(capturedImageUri, null, null);
I got the following output (and a crash of course):
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {nightout.dk.nightoutandroid/nightout.dk.nightoutandroid.MainActivity}: java.lang.IllegalArgumentException: Unknown URL file:///storage/emulated/0/Pictures/nightout/1450477843900.jpg
at android.app.ActivityThread.deliverResults(ActivityThread.java:3790)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3833)
at android.app.ActivityThread.access$1700(ActivityThread.java:152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5538)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.IllegalArgumentException: Unknown URL file:///storage/emulated/0/Pictures/nightout/1450477843900.jpg
at android.content.ContentResolver.delete(ContentResolver.java:1323)
at nightout.dk.nightoutandroid.views.PicturesView.manageCapturedPicture(PicturesView.java:137)
at nightout.dk.nightoutandroid.views.PicturesView.receiveStringMessage(PicturesView.java:197)
at nightout.dk.nightoutandroid.services.eventbus.EventBus.postStringMessage(EventBus.java:39)
at nightout.dk.nightoutandroid.MainActivity.onActivityResult(MainActivity.java:158)
at android.app.Activity.dispatchActivityResult(Activity.java:6238)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3786)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3833)
at android.app.ActivityThread.access$1700(ActivityThread.java:152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5538)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
In Java, to delete a file, create a File
object pointing to that file, and call delete()
on that File
object.
Note that since it is possible that you will undergo a configuration change or have your process terminated while the camera app is in the foreground, make sure to save the path to the file in your saved instance state Bundle
and restore it from there.
With respect to your manageCapturedPicture()
method:
Please do not index an image in the MediaStore
if you intend on deleting it milliseconds later
Feel free to use decodeFile()
on BitmapFactory
, since this is a file that you control
Please use BitmapFactory.Options
and scale the image as part of reading it in, rather than wasting nearly twice the heap space by reading in the full image and then scaling it
Do not try to delete()
something from a ContentProvider
that you did not get from the ContentProvider