Android Camera Code Tutorial

Published by - @ninjazhai on November 17, 2012
LIKE and SHARE:

Today we are going to do a code that can enable your android application to capture images using the device camera. In this example code, we will have:

  1. A “Take Picture” button on our main activity, when the user clicks it, the device camera will be shown that will enable your user the take a picture.
  2. After taking a picture, the preview of the image will be shown with options to “Save” or “Discard” the image.
  3. If the user tapped “Save”, the image will be saved on the directory we specified in our code, else, if the user tapped “Discard”, the device camera will be shown again.
  4. If the user saved the image, he will be asked if he wants to take another picture.

Android Camera Code Tutorial

DOWNLOAD SOURCE CODE

Our MainActivity.java code – This activity will show our “Take Picture” button.

package com.example.camerahelper;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.View;

public class MainActivity extends Activity {

    Context mContext;

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

        mContext = MainActivity.this;

        View.OnClickListener handler = new View.OnClickListener() {
            public void onClick(View v) {

                switch (v.getId()) {

                case R.id.takePicture:
                    // go to camera activity
                    Intent nextActivity = new Intent(mContext,
                            CameraActivity.class);
                    startActivity(nextActivity);
                    break;

                }
            }
        };

        findViewById(R.id.takePicture).setOnClickListener(handler);

    }

}

Our res/layout/activity_main.xml – The XML layout file for our MainActivity.

<?xml version=“1.0″ encoding=“utf-8″?>
<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   android:id=“@+id/widget29″
   android:layout_width=“fill_parent”
   android:layout_height=“fill_parent” >
    <Button
       android:id=“@+id/takePicture”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_centerHorizontal=“true”
       android:layout_centerVertical=“true”
       android:text=“@string/take_picture” />

</RelativeLayout>

Our CameraActivity.java – This code does almost all the operations from starting the device camera to saving the image to specified directory.

package com.example.camerahelper;
import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

public class CameraActivity extends Activity {

    private static final String LOG_TAG = “CameraActivity.java”;
    private static final int IMAGE_CAPTURE = 0;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);

        try {

            // intent to start device camera
            Intent intent = new Intent(“android.media.action.IMAGE_CAPTURE”);

            // you can also create your own filename or path
            String fileName = “codeofaninja_app”;

            // where do you want to save the images
            String path = Environment.getExternalStorageDirectory() + “/”
                    + fileName + “.jpg”;

            File file = new File(path);

            // if the file name already exists, append __x on the file name
            int x = 2;
            while (file.exists()) {

                path = Environment.getExternalStorageDirectory() + “/”
                        + fileName + “__” + x + “.jpg”;
                file = new File(path);

                x++;
            }

            Uri outputFileUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            // 0, this code will be returned in onActivityResult() when the
            // activity exits.
            startActivityForResult(intent, 0);

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // activity exits
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        try {
            if (requestCode == IMAGE_CAPTURE) {
                if (resultCode == RESULT_OK) {

                    Log.v(LOG_TAG, “Picture taken.”);

                    // delete last image from dcim
                    if(!deleteLastSavedDcimImage()){
                        Log.v(LOG_TAG,“Unable to delete last saved image in /Camera/DCIM/”);
                    }

                    // ask if the user want’s to take another picture
                    takeAnother();

                } else {
                    // you can specify any message here
                    // or just remove it
                    Toast.makeText(getBaseContext(),
                            “Error: Result code is not RESULT_OK.”,
                            Toast.LENGTH_SHORT).show();

                }
            } else {
                // you can specify any message here
                // or just remove it
                Toast.makeText(getBaseContext(),
                        “Error: Request code is not IMAGE_CAPTURE.”,
                        Toast.LENGTH_SHORT).show();
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onBackPressed() {
        CameraActivity.this.finish();
    }

    public void takeAnother() {
        try {

            new AlertDialog.Builder(this).setTitle(“The Code Of A Ninja”)
                    .setMessage(“Do you want to take another picture?”)
                    .setPositiveButton(“YES”, new OnClickListener() {
                        public void onClick(DialogInterface arg0, int arg1) {
                            arg0.dismiss();

                            Intent nextActivity = new Intent(
                                    CameraActivity.this, CameraActivity.class);
                            CameraActivity.this.finish();
                            startActivity(nextActivity);

                        }
                    })

                    .setNegativeButton(“NO”, new OnClickListener() {
                        public void onClick(DialogInterface arg0, int arg1) {

                            arg0.dismiss();

                            Toast.makeText(CameraActivity.this,
                                    “Done taking picture.”, Toast.LENGTH_LONG)
                                    .show();

                            // go to main activity
                            CameraActivity.this.finish();

                        }
                    }).show();

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // since our code also saves the taken images to DCIM/Camera folder of the
    // device, we have to delete it there so that the image will be saved
    // only to the directory we have specified.
    private boolean deleteLastSavedDcimImage() {

        Log.v(LOG_TAG, “Deleting late image from DCIM.”);

        boolean success = false;

        try {

            // list the images in the device /DCIM/Camera directory
            File[] images = new File(Environment.getExternalStorageDirectory()
                    + “/DCIM/Camera”).listFiles();
            File lastSavedImage = images[0];
            int imagesLen =  images.length;
            
            //loop and check for the last modified image to get the last save image
            for (int i = 1; i < imagesLen; ++i) {
                if (images[i].lastModified() > lastSavedImage.lastModified()) {
                    lastSavedImage = images[i];
                }
            }

            //then delete the last saved image
            success = new File(lastSavedImage.toString()).delete();

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return success;
    }
}

Our res/layout/camera.xml code – XML I used for our CameraActivity.java activity

<?xml version=“1.0″ encoding=“utf-8″?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   android:layout_width=“fill_parent”
   android:layout_height=“fill_parent”
   android:orientation=“vertical” >
    <TextView
       android:id=“@+id/textView1″
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:text=“” >
    </TextView>

</LinearLayout>

The AndroidManifest.xml code – This will give us permission to use the device camera hardware.

<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
   package=“com.example.camerahelper”
   android:versionCode=“1″
   android:versionName=“1.0″ >
    <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE” />
    <uses-permission android:name=“android.permission.CAMERA” />

    <uses-feature android:name=“android.hardware.camera” />
    <uses-feature android:name=“android.hardware.camera.autofocus” />

    <uses-sdk
       android:minSdkVersion=“8″
       android:targetSdkVersion=“15″ />

    <application
       android:icon=“@drawable/ic_launcher”
       android:label=“@string/app_name”
       android:theme=“@style/AppTheme” >
        <activity
           android:name=“.MainActivity”
           android:label=“@string/title_activity_main” >
            <intent-filter>
                <action android:name=“android.intent.action.MAIN” />

                <category android:name=“android.intent.category.LAUNCHER” />
            </intent-filter>
        </activity>
        <activity android:name=“.CameraActivity” >
        </activity>
    </application>

</manifest>

Some output screenshots:

11

22

33

The Code of a Ninja Resources

  • http://www.netspysoftware.com/blackberry-spy.html Emilia

    Interesting!I’m in the process of learning Java and this will certainly help me a lot. Btw, I’ve bookmarked your website.

  • http://www.blogger.com/profile/05733400401287031490 Mike Dalisay

    Thanks for the bookmark too Emilia! :D

  • http://www.blogger.com/profile/17176463315975589141 Daniel Schmidt

    Hey Mike,

    great Tutorial, i follow you on Twitter now :)

    I finished your tutorial and everything works very well. My question is, can you show how to display the new shot photos from the app in camera.xml ? Would be nice if you could select one of the photos and send it to another view of the app.

    Greetings Dan

  • http://www.blogger.com/profile/05733400401287031490 Mike Dalisay

    Hi, thanks Dan!

    I think you can save the path of the newly shot photo to a SharedPreference and create a new activity with an ImageView. After the photo was taken, you can start the new activity and using the saved path, you can load the image to the ImageView..

  • Anonymous

    Hi’
    I have downloaded your project but its giving me Unexpectedly Closed error.

  • http://www.blogger.com/profile/05733400401287031490 Mike Dalisay

    @Anon: Hi thanks for visiting, what does your logcat says?

  • http://www.squamble.com/2013/01/28/facebook-graph-search/ Android Track

    I just recently enrolled in programming class and this article will be very helpful for me. It can serve as my guide as I try to explore my android phone. hopefully I won’t mess up with it.

  • http://www.blogger.com/profile/05733400401287031490 Mike Dalisay

    @Android Track: I’m glad my article can help! If you have determination and focus, you won’t mess it up for sure! :D