Saving image taken from camera into INTERNAL storage

37,654

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();
      }
    }
  }
}
Share:
37,654
undorealize
Author by

undorealize

Updated on July 29, 2020

Comments

  • undorealize
    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
    undorealize almost 9 years
    Thank 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
    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 the MediaStore, and what you see over your USB cable connection is what MediaStore knows about. Use MediaScannerConnection and scanFile() to update the MediaStore in real time.
  • undorealize
    undorealize almost 9 years
    I 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
    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.