How to Get URI of Captured Photo

how-to-get-uri-of-captured-photo-thumb

24th February, 2020

Hello Developer! In this section you will learn how to get URI of captured photo.

Step 1: Setup File Provider

First you have to setup the File Provider that gives you URI in the content:// format. The following image describes the file provider’s directory in the project. Create a file inside XML folder and write below code in it.

file-provider-XML
Project ⇒ app ⇒ src ⇒ main ⇒ res ⇒ xml ⇒ provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

Now open AndroidManifest.xml file and add file provider before </application> tag.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.codestringz.mytestapp">

    <uses-permission android:name="android.permission.CAMERA"/>

    <application
        ...
		...>
        <activity
			...
			.../>
        <activity
			...
			.../>
			
		<!--File Provider-->
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
		
    </application>

</manifest>

Step 2: Add Camera Permission

The user’s camera will be used by the app to capture photos. So add camera-permission to AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA"/>

Check runtime permission on android

As of API level 23, Permission to use the camera is classified in the list of dangerous permissions. Therefore you need to check the runtime permission before sending the intent for camera.

//If the API Level is 23 or above, Check the Runtime Permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
	if (checkSelfPermission(mPermission) != PackageManager.PERMISSION_GRANTED)
	{
		//Permission not granted. request permission
		ActivityCompat.requestPermissions(MainActivity.this, new String[]{mPermission}, REQUEST_CODE_IMAGE_CAPTURE);
	} else
	{
		//Permission granted
		dispatchTakePictureCamIntent();
	}
} else
{
	//API Level is below 23 -> runtime permission not required
	dispatchTakePictureCamIntent();
}

Then override onRequestPermissionsResult to handle result of the requested permissions.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
	super.onRequestPermissionsResult(requestCode, permissions, grantResults);

	if (requestCode == REQUEST_CODE_IMAGE_CAPTURE)
	{
		if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
		{
			//Permission granted
			dispatchTakePictureCamIntent();
		} else
		{
			//Permission denied
		}
	}
}

Step 3: Start Intent for Camera

After adding File Provider and Permission, Start intent for the camera.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="www.CodestringZ.com" />

    <ImageView
        android:id="@+id/displayImageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"
        android:adjustViewBounds="true"
        android:src="@mipmap/ic_launcher"
        tools:ignore="ContentDescription" />

    <Button
        android:id="@+id/cameraButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/displayImageView"
        android:layout_centerHorizontal="true"
        android:text="Open Camera" />

</RelativeLayout>
package com.codestringz.mytestapp;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

public class MainActivity extends AppCompatActivity
{

    private static final int REQUEST_CODE_IMAGE_CAPTURE = 5484;
    private String mPermission = Manifest.permission.CAMERA;
    private Uri mCapturedPhotoUri;
    private ImageView mDisplayImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setUIRef();
    }

    private void setUIRef()
    {
        //---Set UI References---//

        mDisplayImageView = findViewById(R.id.displayImageView);

        Button cameraButton = findViewById(R.id.cameraButton);
        cameraButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //If the API Level is 23 or above, Check the Runtime Permission
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                {
                    if (checkSelfPermission(mPermission) != PackageManager.PERMISSION_GRANTED)
                    {
                        //Permission not granted. request permission
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{mPermission}, REQUEST_CODE_IMAGE_CAPTURE);
                    } else
                    {
                        //Permission granted
                        dispatchTakePictureCamIntent();
                    }
                } else
                {
                    //API Level is below 23 -> runtime permission not required
                    dispatchTakePictureCamIntent();
                }
            }
        });
    }

    private void dispatchTakePictureCamIntent()
    {
        //Create intent for the Camera
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null)
        {
            // Create the File
            File photoFile = null;
            try
            {
                photoFile = createImageFile(this.getApplicationContext());
            } catch (IOException ex)
            {
                //Error occurred while creating the File
            }
            // Continue only if the File was successfully created
            if (photoFile != null)
            {
                Uri photoUri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                startActivityForResult(takePictureIntent, REQUEST_CODE_IMAGE_CAPTURE);
                mCapturedPhotoUri = photoUri;
            }
        }
    }

    public File createImageFile(Context context) throws IOException
    {
        //Create Image Name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmsss", Locale.US).format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        //noinspection UnnecessaryLocalVariable
        File imageFile = File.createTempFile(imageFileName, ".jpg", storageDir);

        return imageFile;
    }

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

        if (requestCode == REQUEST_CODE_IMAGE_CAPTURE && resultCode == RESULT_OK)
        {
            if (mCapturedPhotoUri != null)
            {
                //Set Uri to ImageView
                mDisplayImageView.setImageURI(mCapturedPhotoUri);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQUEST_CODE_IMAGE_CAPTURE)
        {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //Permission granted
                dispatchTakePictureCamIntent();
            } else
            {
                //Permission denied
            }
        }
    }
}

Output

img-get-uri-of-captured-photo-output

Happy coding!

Leave a Reply