[android] Getting path of captured image in Android using camera intent

I have been trying to get path of captured image in order to delete image. Found many answers on StackOverflow but none of them are working for me. I got the following answer:

private String getLastImagePath() {
    final String[] imageColumns = { MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
    Cursor imageCursor = POS.this.getContentResolver().query(
            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));
        return fullPath;
    } else {
        return "";
    }
}

This code works in Samsung tab but doesn't work in Lenovo tab and i-ball tab. So, can anyone help me find another solution to do the same? Any help will be appreciated. Thank you.

This is my onActivityResult:

if (requestCode == CmsInter.CAMERA_REQUEST && resultCode == RESULT_OK) {
    //Bitmap photo = null;
    //photo = (Bitmap) data.getExtras().get("data");

    String txt = "";
    if (im != null) {
        String result = "";
        //im.setImageBitmap(photo);
        im.setTag("2");
        int index = im.getId();
        String path = getLastImagePath();
        try {
            bitmap1 = BitmapFactory.decodeFile(path, options);
            bitmap = Bitmap.createScaledBitmap(bitmap1, 512, 400, false);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] bytData = baos.toByteArray();
            try {
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            result = Base64.encode(bytData);
            bytData = null;
        } catch (OutOfMemoryError ooM) {
            System.out.println("OutOfMemory Exception----->" + ooM);
            bitmap1.recycle();
            bitmap.recycle();
        } finally {
            bitmap1.recycle();
            bitmap.recycle();
        }
    }
}

This question is related to android android-camera-intent

The answer is


try this

String[] projection = { MediaStore.Images.Media.DATA };
            @SuppressWarnings("deprecation")
            Cursor cursor = managedQuery(mCapturedImageURI, projection,
                    null, null, null);
            int column_index_data = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            image_path = cursor.getString(column_index_data);
            Log.e("path of image from CAMERA......******************.........",
                    image_path + "");

for capturing image:

    String fileName = "temp.jpg";
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, fileName);
    mCapturedImageURI = getContentResolver().insert(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
    values.clear();

There is a solution to create file (on external cache dir or anywhere else) and put this file's uri as output extra to camera intent - this will define path where taken picture will be stored.

Here is an example:

File file;
Uri fileUri;
final int RC_TAKE_PHOTO = 1;

    private void takePhoto() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        file = new File(getActivity().getExternalCacheDir(), 
                String.valueOf(System.currentTimeMillis()) + ".jpg");
        fileUri = Uri.fromFile(file);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        getActivity().startActivityForResult(intent, RC_TAKE_PHOTO);

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RC_TAKE_PHOTO && resultCode == RESULT_OK) {

                //do whatever you need with taken photo using file or fileUri

            }
        }
    }

Then if you don't need the file anymore, you can delete it using file.delete();

By the way, files from cache dir will be removed when user clears app's cache from apps settings.


Here I updated the sample code in Kotlin. Please note on Nougat and above version Uri.fromFile(file) is not working and it crashes the app for that need to implement FileProvider which is safest way to send files from intent. For implementing this refer this answer or this article

private fun takePhotoFromCamera() {
        val isDeviceSupportCamera: Boolean = this.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
        if (isDeviceSupportCamera) {
            val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                file = File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS + "/attachments")!!.path,
                        System.currentTimeMillis().toString() + ".jpg")
//            fileUri = Uri.fromFile(file)
                fileUri = FileProvider.getUriForFile(this, this.applicationContext.packageName + ".provider", file!!)
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
                    takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                }
                startActivityForResult(takePictureIntent, Constants.REQUEST_CODE_IMAGE_CAPTURE)
            }

        } else {
            Toast.makeText(this, this.getString(R.string.camera_not_supported), Toast.LENGTH_SHORT).show()
        }
    }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
             if(requestCode == Constants.REQUEST_CODE_IMAGE_CAPTURE) {
                realPath = file?.path
                 //do what ever you want to do
            }
    }
}

Please refer to Google Documentation: Camera - Photo Basics


Try this method to get path of original image captured by camera.

public String getOriginalImagePath() {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getActivity().managedQuery(
                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);
    }

This method will return path of the last image captured by camera. So this path would be of original image not of thumbnail bitmap.