Saving image taken from camera into INTERNAL storage
getOutputMediaFile()
is returning a directory, not a file. You need to specify a path to a (not-yet-existing) file where you want the image to be written.
This is illustrated in this activity from this sample application:
package com.commonsware.android.camcon;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
public class CameraContentDemoActivity extends Activity {
private static final int CONTENT_REQUEST=1337;
private File output=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File dir=
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
output=new File(dir, "CameraContentDemo.jpeg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(output));
startActivityForResult(i, CONTENT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == CONTENT_REQUEST) {
if (resultCode == RESULT_OK) {
Intent i=new Intent(Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(output), "image/jpeg");
startActivity(i);
finish();
}
}
}
}
undorealize
Updated on July 29, 2020Comments
-
undorealize almost 4 years
I just got started in Android Programming and I am creating an android application in which the user is allowed to key in information, take a picture with ImageView implemented and SAVE the information. I've gotten up to the point where I am able to display the image taken into ImageView. However, I am unable to save the image taken into my phone's internal storage. Which means, whenever I try to save the information, including the ImageView (image from camera), only the image disappears. I've followed this guide on http://www.androidhive.info/2013/09/android-working-with-camera-api/ but it does not work as my phone has no SD card storage.
I've read a bunch of questions on here but they do not fix the problem.
So if anyone could give me a detailed procedure on how to edit this code in such a way that I can save/read the image into/from my INTERNAL storage that would be great! Thank you.
/** * returning image / video */ private static File getOutputMediaFile(int type) { // External sdcard location File mediaStorageDir = new File( Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME); // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory"); return null; } } }
This is my current code:
private static final String IMAGE_DIRECTORY_NAME = "Hello Camera"; private Uri fileUri; // file url to store image/video private ImageView ItemPic; private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100; public static final int MEDIA_TYPE_IMAGE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.new_entry); date = (EditText) findViewById(R.id.date); amount = (EditText) findViewById(R.id.amount); item = (EditText) findViewById(R.id.item); add = (Button) findViewById(R.id.add_b); add.setOnClickListener(onAdd); camera = (ImageButton) findViewById(R.id.camera); camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // capture picture captureImage(); // Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); // startActivityForResult(cameraIntent, CAMERA_REQUEST); } }); ItemPic = (ImageView) findViewById(R.id.itempic); entryId = getIntent().getStringExtra("ID"); if (entryId != null) { load(); } } /* * Capturing Camera Image will lauch camera app requrest image capture */ private void captureImage() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // start the image capture Intent startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); } /** * Here we store the file url as it will be null after returning from camera * app */ @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // save file url in bundle as it will be null on scren orientation // changes outState.putParcelable("file_uri", fileUri); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); // get the file url fileUri = savedInstanceState.getParcelable("file_uri"); } /** * Receiving activity result method will be called after closing the camera * */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // if the result is capturing Image if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) { if (resultCode == RESULT_OK) { // successfully captured the image // display it in image view previewCapturedImage(); } else if (resultCode == RESULT_CANCELED) { // user cancelled Image capture Toast.makeText(getApplicationContext(), "User cancelled image capture", Toast.LENGTH_SHORT) .show(); } else { // failed to capture image Toast.makeText(getApplicationContext(), "Sorry! Failed to capture image", Toast.LENGTH_SHORT) .show(); } } } /** * Display image from a path to ImageView */ private void previewCapturedImage() { try { ItemPic.setVisibility(View.VISIBLE); // bimatp factory BitmapFactory.Options options = new BitmapFactory.Options(); // downsizing image as it throws OutOfMemory Exception for larger // images options.inSampleSize = 8; final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options); ItemPic.setImageBitmap(bitmap); } catch (NullPointerException e) { e.printStackTrace(); } } /** * ------------ Helper Methods ---------------------- * */ /** * Creating file uri to store image/video */ public Uri getOutputMediaFileUri(int type) { return Uri.fromFile(getOutputMediaFile(type)); } /** * returning image / video */ private static File getOutputMediaFile(int type) { // External sdcard location File mediaStorageDir = new File( Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), IMAGE_DIRECTORY_NAME); // Create the storage directory if it does not exist if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); } else { return null; } return mediaFile; }
-
undorealize almost 9 yearsThank you! I've tried your code and was able to preview the image in my gallery after capturing the image, however, it still does not save...
-
CommonsWare almost 9 years@undorealize: By definition, if the activity started by
onActivityResult()
can show you the image, the image saved. However, bear in mind that the image may not have been indexed by theMediaStore
, and what you see over your USB cable connection is whatMediaStore
knows about. UseMediaScannerConnection
andscanFile()
to update theMediaStore
in real time. -
undorealize almost 9 yearsI was able to save the image taken from the camera however, I've noticed that when I take consecutive shots, the previous photo gets overwritten. How do I change that?
-
CommonsWare almost 9 years@undorealize: Provide a different value for
EXTRA_OUTPUT
. You are the one indicating where the images should be written. It is your job to recognize that you are taking consecutive shots, and it is your job to use different filenames for those shots if you want all the files to be saved.