Skip to the content.

Taking a photo from your app on Android

Taking a photo from your app on Android is not difficult, but it’s not just starting an activity using an intent with MediaStore.ACTION_IMAGE_CAPTURE.

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class CameraActivity extends Activity
{
    public void takePhoto() {
        try {
            // Some apps create a temporary row in the content provider and pass its Uri like:
            //
            //     ContentValues values = new ContentValues();
            //     values.put(MediaStore.Images.Media.TITLE, filename);
            //     values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            //     imageForCamera_ = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            //
            // but that's not a good idea because a user will see the temporary image
            // if they switch to Media App before taking a photo.
            imageFileForCamera_ = File.createTempFile("camera", ".jpg", getTemporaryDirectory());

            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFileForCamera_));
            startActivityForResult(cameraIntent, REQUEST_CAMERA);
        }
        catch (IOException e) {
            // Show an error.
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        // Because this activity may be destroyed while Camera App is active,
        // restore the path of the temporary file.
        imageFileForCamera_ = (File)savedInstanceState.getSerializable(INSTANCE_STATE_IMAGE_FILE_FOR_CAMERA);
    }

    @Override
    protected void onSaveInstanceState(Bundle outInstanceState) {
        super.onSaveInstanceState(outInstanceState);

        // Because this activity may be destroyed while Camera App is active,
        // save the path of the temporary file.
        outInstanceState.putSerializable(INSTANCE_STATE_IMAGE_FILE_FOR_CAMERA, imageFileForCamera_);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        case REQUEST_CAMERA:
            try {
                if (resultCode == RESULT_OK) {
                    // Some devices, such as Xperia, don't save the image
                    // to the file specified with MediaStore.EXTRA_OUTPUT,
                    // and returns it via data.
                    Uri uri = data != null ? data.getData() : null;
                    if (uri == null)
                        uri = Uri.fromFile(imageFileForCamera_);

                    if (data == null) {
                        // The devices which return the image via data store it
                        // in the media store automatically.
                        try {
                            MediaStore.Images.Media.insertImage(getContentResolver(), imageFileForCamera_.getAbsolutePath(), null, null);
                        }
                        catch (FileNotFoundException e) {
                            // Show an error.
                        }
                    }

                    String path = resolveContentUriToPath(uri);

                    // Use path here.

                }
            }
            finally {
                imageFileForCamera_.delete();
                imageFileForCamera_ = null;
            }
            break;
        }
    }

    private String resolveContentUriToPath(Uri uri) {
        if (uri.getScheme().equals("file")) {
            return uri.getPath();
        }
        else {
            Cursor cursor = getContentResolver().query(uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null);
            return cursor != null && cursor.moveToFirst() ? cursor.getString(0) : null;
        }
    }

    private File getTemporaryDirectory() {
        // Use .tmp as a name of a temporary directory
        // so that Media App won't list files in it.
        return new File(getExternalFilesDir(null), ".tmp");
    }

    private File imageFileForCamera_;

    private static final int REQUEST_CAMERA = 1;
    private static final String INSTANCE_STATE_IMAGE_FILE_FOR_CAMERA = "imageFileForCamera";
}