Android Basic Training Course: Working with Camera and Image Gallery

    Sometimes, in your Android application, you’ll want the user to choose an image from the gallery or device camera. With camera, we can take a photo directly at the moment and call back data (taken photo in Bitmap format) to our application, and with Gallery apps which available in our device (Gallery, Photos, ES File Explorer, etc), we can get any image storing on device memory in Uri format to our application. Both of 2 ways use Intent and sub-Activity.

Take photo from Camera

    Firstly, you must request camera using permission with your app first in AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA"/>
    In code, creating an Intent with action String is MediaStore.ACTION_IMAGE_CAPTURE, start a sub Activity like this:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PICK); //CAMERA_PICK is a final int variable!
    Handling data (in Bitmap format after taking a photo by overriding onActivityResult():
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == CAMERA_PICK && resultCode == RESULT_OK) {
            Bitmap photo = (Bitmap) data.getExtras().get("data");
            //set photo bitmap to ImageView
            imageView.setImageBitmap(photo);
        } 
    }
NOTE: RESULT_OK is code when we taking a photo from camera successfully.

Get Photo from Gallery

    In order to access to device memory to get file (in this case is photos), you must request reading data permission:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Absolutely similar with using Camera, you can open a dialog to choosing a Gallery app by Intent with ACTION_GET_CONTENT:
Intent intent = new Intent();
intent.setType("image/*"); //set type for files (image type)
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_FROM_GALLERY); //PICK_FROM_GALLERY is final int variable
And get data back in onActivityResult():
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK) {
            Uri selectedImage = data.getData();
            imageView.setImageURI(selectedImage);
        }
    }

Sample project full code

    Now, I will provide a simple project which allows users perform these 2 actions and get data to ImageView. The main Activity layout:
activity_main.xml
<?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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="info.devexchanges.pickimages.MainActivity">

    <ImageView
        android:id="@+id/image"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop"
        android:layout_centerHorizontal="true" />

    <Button
        android:id="@+id/btn_camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:drawableLeft="@android:drawable/ic_menu_camera"
        android:text="Pick from Camera" />

    <Button
        android:id="@+id/btn_gallery"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_camera"
        android:drawableLeft="@android:drawable/ic_menu_gallery"
        android:text="Pick from Gallery" />
</RelativeLayout>
    And it's programmatically code:
MainActivity.java
package info.devexchanges.pickimages;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private View btnCamera;
    private View btnGallery;
    private ImageView imageView;
    private static final int CAMERA_PICK = 1;
    private static final int PICK_FROM_GALLERY = 2;

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

        btnCamera = findViewById(R.id.btn_camera);
        btnGallery = findViewById(R.id.btn_gallery);
        imageView = (ImageView) findViewById(R.id.image);

        btnCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA_PICK);
            }
        });

        btnGallery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setType("image/*"); //set type for files (image type)
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_FROM_GALLERY);
            }
        });
    }

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

        if (requestCode == CAMERA_PICK && resultCode == RESULT_OK) {
            Bitmap photo = (Bitmap) data.getExtras().get("data");
            //set photo bitmap to ImageView
            imageView.setImageBitmap(photo);
        } else if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK) {
            Uri selectedImage = data.getData();
            imageView.setImageURI(selectedImage);
        }
    }
}
    Running application, we have this output screen:
 
    After taking a photo from Camera successful, photo will be set to ImageView:

    When clicking at "Pick From Gallery" button, the "Gallery apps chooser" will be displayed:
    And when user choose a app and a photo then, it's also set to ImageView:

Final thoughts

    If you would like Google Play prevents the app to be installed on devices those doesn’t have camera, please adding <uses-feature android:name="android.hardware.camera" /> in your AndroidManifest.xml.
    Another common problem is working with Camera and Gallery in Fragment, your Fragment sometimes stop before onActivityResult() called. This bug happen in some devices have strict memory management (e.g: Samsung Galaxy Tab 4, Samsung Galaxy S3,...), and in order to resolved it, please uncheck "Do not keep Activities" option in Developer Options entry:


Share


Previous post
« Prev Post
Next post
Next Post »