Thursday, 22 February 2018

Android Take Photo from Camera and Gallery


A Simple example application to capture image/ selecting image from gallery.

This application includes sd card permission checking and FileUrilExposedException issue fix..


Step 1:
=========
Create an Activity like below

package org.pratap.cameraexample;

import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

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

public class MainActivity extends AppCompatActivity {


    final int REQUEST_PERMISSIONS = 1001;
    final int DELAY_TIME = 1000;
    private static int NEW_IMAGE = 0;
    private static int EXISTING_IMAGE = 1;

    Button btn_capture_image, btn_galley_image;
    ImageView img_photo;

    String imageFilePath = "";

    int imageType = 0;

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

        btn_capture_image = (Button) findViewById(R.id.btn_capture_image);
        btn_galley_image = (Button) findViewById(R.id.btn_galley_image);
        img_photo = (ImageView) findViewById(R.id.img_photo);


        img_photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                viewImage();


            }
        });

        btn_capture_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkPermissions();
                // for camera image
                imageType = 0;

            }
        });


        btn_galley_image.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkPermissions();

                // for gallery image
                imageType = 1;
            }
        });

    }


    private void checkPermissions() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            mHandler.sendEmptyMessageDelayed(1, DELAY_TIME);
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS);
        }
    }

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

        if (requestCode == REQUEST_PERMISSIONS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted

                mHandler.sendEmptyMessageDelayed(1, DELAY_TIME);
            } else {
                // permission denied, boo!
            }
        }
    }


    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {


                // code goes here after getting permission


                if (imageType == 0) {

                    takePictureFromCamera();
                } else if (imageType == 1) {

                    pictureFromGallery();
                }


            }
        }
    };


    public void takePictureFromCamera() {

        imageFilePath = "";

        File imageFile = createFileName();

        imageFilePath = imageFile.getAbsolutePath();


        Uri outputFileUri = null;


        // if you are running nougat and above there is chance to crash
        if (Build.VERSION.SDK_INT >= 24) {

            outputFileUri = FileProvider.getUriForFile(MainActivity.this,
                    BuildConfig.APPLICATION_ID + ".provider",
                    imageFile);
        } else {
            outputFileUri = Uri.fromFile(imageFile);
        }


        if (outputFileUri != null) {

            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
            startActivityForResult(cameraIntent, NEW_IMAGE);
        } else {

            Toast.makeText(this, "URI not found", Toast.LENGTH_SHORT).show();
        }


    }


    public void pictureFromGallery() {

        try {
            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(i, EXISTING_IMAGE);
        } catch (ActivityNotFoundException anfe) {
            // display an error message
            String errorMessage = "Your device doesn't have gallery";
            Toast toast = Toast
                    .makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toast.show();
        }
    }


    public void viewImage() {


        if (imageFilePath.length() != 0) {


            try {

                File file = new File(imageFilePath);


                String documentType = getFileExtension(file);


                Uri uri = null;

                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);


                if (Build.VERSION.SDK_INT >= 24) {

                    uri = FileProvider.getUriForFile(MainActivity.this,
                            BuildConfig.APPLICATION_ID + ".provider",
                            file);

                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    uri = Uri.fromFile(file);
                }

                if (documentType.equalsIgnoreCase("jpg")) {

                    intent.setDataAndType(uri, "image/jpeg");
                    startActivity(intent);

                } else if (documentType.equalsIgnoreCase("png")) {

                    intent.setDataAndType(uri, "image/png");
                    startActivity(intent);

                } else {


                    intent.setDataAndType(uri, "*/*");
                    startActivity(intent);
                }
            } catch (ActivityNotFoundException e) {
                e.printStackTrace();
            }

        } else {
            Toast.makeText(MainActivity.this, "Image not selected.Please Select Image First", Toast.LENGTH_SHORT).show();
        }

    }


    public File createFileName() {

        final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/CameraEx/Images/";
        File newDir = new File(dir);
        if (!newDir.exists()) {
            newDir.mkdirs();
        }

        String newFilename = "";
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        newFilename = sdf.format(date);


        String filePath = dir + newFilename + ".jpg";
        File newFile = new File(filePath);
        try {
            newFile.createNewFile();
        } catch (IOException e) {
        }

        return newFile;
    }


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

        if (requestCode == EXISTING_IMAGE && resultCode == RESULT_OK
                && null != data) {
            try {

                Uri selectedImage = data.getData();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();


                imageFilePath = picturePath;

                if (imageFilePath.length() != 0) {


                    // set ImageView with File Path
                    setImage(MainActivity.this, imageFilePath, img_photo);
                    Toast.makeText(MainActivity.this, "Image Saved : " + imageFilePath, Toast.LENGTH_SHORT).show();

                } else {
                    Toast.makeText(MainActivity.this, "Image not selected.Please try again", Toast.LENGTH_SHORT).show();
                }

            } catch (Exception e) {

            }


        } else if (requestCode == NEW_IMAGE && resultCode == RESULT_OK) {

            if (imageFilePath.length() != 0) {
                // set ImageView with File Path
                setImage(MainActivity.this, imageFilePath, img_photo);
                Toast.makeText(MainActivity.this, "Image Saved : " + imageFilePath, Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "Image not selected.Please try again", Toast.LENGTH_SHORT).show();
            }


        }


    }


    public void setImage(Context ctx, String filePath, ImageView imgView) {

        File actualImage = new File(filePath);
        if (actualImage.exists()) {

            Glide.with(ctx)
                    .load(actualImage)
                    .centerCrop()
                    .into(imgView);

        } else {
            Toast.makeText(ctx, "No File exists", Toast.LENGTH_SHORT).show();
        }


    }


    public String getFileExtension(File file) {
        String name = file.getName();
        try {
            return name.substring(name.lastIndexOf(".") + 1);
        } catch (Exception e) {
            return "";
        }
    }


}


XML Layout for the Activity

activity_main.xml
==============

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="org.pratap.cameraexample.MainActivity">


    <ImageView
        android:id="@+id/img_photo"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:background="#c9c9c9"
        android:scaleType="centerCrop" />


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="24dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_capture_image"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Capture Image" />


        <Button
            android:id="@+id/btn_galley_image"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Galley Image" />

    </LinearLayout>


</LinearLayout>



ScreenShot for Preview:



 



Step 2:
=========

Add the following code in AndroidManifest.xml


   <provider
            android:name="android.support.v4.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>


like below




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


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


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <provider
            android:name="android.support.v4.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 3:
=====

create provider_paths xml file under xml folder

path should be like this

res/xml/provider_path.xml



<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>




Some useful methods to convert Files to ByteArray or Base64 Encoded String


public static String getEncodedString(String filePath) throws FileNotFoundException, IOException {

        String encodedDocument = "";


        File file = new File(filePath);
        byte[] binaryFile = new byte[(int) file.length()];
        InputStream fis = new FileInputStream(file);


        fis.read(binaryFile);
        fis.close();


        encodedDocument = Base64.encodeToString(binaryFile,
                Base64.DEFAULT);


        return encodedDocument;

    }


    public static byte[] getFileByteArray(String filePath) throws FileNotFoundException, IOException {

        File file = new File(filePath);


        FileInputStream fis = new FileInputStream(file);


        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[(int) file.length()];
        try {
            for (int readNum; (readNum = fis.read(buf)) != -1; ) {
                bos.write(buf, 0, readNum);


            }
        } catch (IOException ex) {
            Log.d("error", "error");
        }
        byte[] imagebytes = bos.toByteArray();


        return imagebytes;

    }








No comments:

Post a Comment