My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
CameraTutorial  
Android Camera Integration
Updated Feb 26, 2011 by openmobs...@gmail.com

Related Links: Beginner Area


Introduction

A simple guide for integrating the Camera Hardware inside your Android App.

Step 1: Create a class that extends SurfaceView and implements SurfaceHolder.Callback

Before you can integrate the Camera hardware with your Activity, you must provide a Preview screen. The camera's Preview output is supplied to this screen. The SurfaceView instance with a SurfaceHolder.Callback implementation provides such a View

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
	private SurfaceHolder holder;
	private Camera camera;
	
	public CameraSurfaceView(Context context) 
	{
		super(context);
		
		//Initiate the Surface Holder properly
		this.holder = this.getHolder();
		this.holder.addCallback(this);
		this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

Step 2: In the surfaceCreated method, get an instance of the Camera

        @Override
	public void surfaceCreated(SurfaceHolder holder) 
	{
		try
		{
			//Open the Camera in preview mode
			this.camera = Camera.open();
			this.camera.setPreviewDisplay(this.holder);
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace(System.out);
		}
	}

Step 3: In the surfaceChanged callback

        @Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
	{
		// Now that the size is known, set up the camera parameters and begin
		// the preview.
		Camera.Parameters parameters = camera.getParameters();
		parameters.setPreviewSize(width, height);
		camera.setParameters(parameters);
		camera.startPreview();
	}

During this callback, you get an idea of how big your preview screen is going to be. Based on that, assign the proper size to the Camera.

Step 4: Implement surfaceDestroyed to cleanup

        @Override
	public void surfaceDestroyed(SurfaceHolder holder) 
	{
		// Surface will be destroyed when replaced with a new screen
		//Always make sure to release the Camera instance
		camera.stopPreview();
		camera.release();
		camera = null;
	}

When the preview screen is removed from view, this callback is used to perform cleanup. In this phase, make sure the preview is stopped and the Camera hardware is released

Step 5: Add the SurfaceView to your layout

                //Setup the FrameLayout with the Camera Preview Screen
		final CameraSurfaceView cameraSurfaceView = new CameraSurfaceView(this);
		FrameLayout preview = (FrameLayout)ViewHelper.findViewById(this, "preview"); 
		preview.addView(cameraSurfaceView);

Step 6: Add a Button for Taking the Picture

//Setup the 'Take Picture' button to take a picture
		Button takeAPicture = (Button)ViewHelper.findViewById(this, "buttonClick");
		takeAPicture.setOnClickListener(new OnClickListener() 
		{
			public void onClick(View v) 
			{
				Camera camera = cameraSurfaceView.getCamera();
				camera.takePicture(null, null, new HandlePictureStorage());
			}
		});

You must supply a Callback to process the information that the camera sends back to your App

        private class HandlePictureStorage implements PictureCallback
	{

		@Override
		public void onPictureTaken(byte[] picture, Camera camera) 
		{
			//The picture can be stored or do something else with the data
			//in this callback such sharing with friends, upload to a Cloud component etc
			
			//This is invoked when picture is taken and the data needs to be processed
			System.out.println("Picture successfully taken: "+picture);
			
			String fileName = "shareme.jpg";
			String mime = "image/jpeg";
			
			MainActivity.this.shareme = new CloudPhoto();
			MainActivity.this.shareme.setFullName(fileName);
			MainActivity.this.shareme.setMimeType(mime);
			MainActivity.this.shareme.setPhoto(picture);
		}
	}

Inside this callback, you can do whatever you need with the picture. You can store it on your local file system, in a sqlite database, or in this case, send it to a remote service located in the cloud.

Step 7: Acquire permission for using the Camera hardware

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

You can do this in the AndroidManifest.xml by adding the above mentioned line

Full Source for CameraSurfaceView.java

package org.openmobster.app;

import java.io.IOException;

import android.content.Context;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.hardware.Camera;

/**
 * 
 * @author openmobster@gmail.com
 */
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
	private SurfaceHolder holder;
	private Camera camera;
	
	public CameraSurfaceView(Context context) 
	{
		super(context);
		
		//Initiate the Surface Holder properly
		this.holder = this.getHolder();
		this.holder.addCallback(this);
		this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) 
	{
		try
		{
			//Open the Camera in preview mode
			this.camera = Camera.open();
			this.camera.setPreviewDisplay(this.holder);
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace(System.out);
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
	{
		// Now that the size is known, set up the camera parameters and begin
		// the preview.
		Camera.Parameters parameters = camera.getParameters();
		parameters.setPreviewSize(width, height);
		camera.setParameters(parameters);
		camera.startPreview();
	}


	@Override
	public void surfaceDestroyed(SurfaceHolder holder) 
	{
		// Surface will be destroyed when replaced with a new screen
		//Always make sure to release the Camera instance
		camera.stopPreview();
		camera.release();
		camera = null;
	}
	
	public Camera getCamera()
	{
		return this.camera;
	}
}

Download this tutorial

  • Go to the cloud directory: mvn -PrunCloud integration-test
  • Go the the app-android directory: mvn -Phot-deploy install
  • Go to the DevCloud app and activate the device with the Cloud
  • Run the CloudCamera app

Related Links: Beginner Area

Comment by project member openmobs...@gmail.com, Feb 26, 2011

When activating the device using the DevCloud?, if you get a "System Error", just go to the "Change Cloud IP" option in the Menu and key in the IP address where your Cloud instance is running. The instance that was started with the mvn -PrunCloud? integration-test command. More details available in this bug report: http://code.google.com/p/openmobster/issues/detail?id=43

Comment by rajiv.ja...@gmail.com, Jun 15, 2011

I have use this code but the problem is when the camera is open it camera preview is opening with rotation in 90 degree..

Comment by project member openmobs...@gmail.com, Jun 20, 2011

I am not quite sure why its rotated. Is this on a device or an emulator?. The emulators on Android API 9+ have better camera emulation (more realistic). I am not sure if this issue is code related since I am not specifying and rotation related configuration

Thanks Sohil

Comment by arive...@gmail.com, Jun 23, 2011

When I run the code it stopped unexpectedly and I didn't saw anything.

Comment by project member openmobs...@gmail.com, Jun 25, 2011

were there any error messages or stack traces you can share?

Comment by asishap...@gmail.com, Jul 7, 2011
arive...@gmail.com: did u set the camera permission in Android manifest?
Comment by yury.ko...@gmail.com, Jul 26, 2011

Nice tutorial, thanks. The only minor issue is that the code violates the direct instruction to immediately release camera in activity's onPause (http://developer.android.com/reference/android/hardware/Camera.html, Class Overview, step #10). Based on my experience the "surfaceDestroyed" callback gets fired only some time after activity's "onPause". And let's say you want to start another activity that also uses Camera - then another activity may fail to open the shared camera resource.

Comment by roe...@gmail.com, Aug 24, 2011

i have the same 90 degree problem... don't know how to set it up... any thoughts?


Sign in to add a comment
Powered by Google Project Hosting