Programming camera in Android

Download source code of this article.

Almost all mobile phones have a built in digital camera. Android phones are no exception. In Android device, to access the camera hardware we use Camera class along with SurfaceView.

The Camera class let you change the settings, preview and take still pictures. The SurfaceView class is used to show the preview to the user. To use the camera feature you should have the android.permission.CAMERA permission.

First we create a SurfaceView to show the live preview. The SurfaceView class holds the surface to draw. We use the interface SurfaceHolder to access the underlying surface. We implement the callback interface SurfaceHolfer.Callback and add this to the SurfaceHolder using SurfaceHolder.addCallback method. The SurfaceHolfer.Callback interface has three methods:

abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
abstract void surfaceCreated(SurfaceHolder holder)
abstract void surfaceDestroyed(SurfaceHolder holder)

The surfaceCreated method will be called after the surface is created, surfaceChanged will be after any changes have been made to the surface and surfaceDestroyed will be called after the surface is destroyed.

To find more about the SurfaceView and SurfaceHolder interface refer to the Google documentation.

Once our surface is created we open the Camera using Camera.open() method. After opening the camera, we set the live preview surface using setPreviewDisplay() method of the Camera class. We open and set the preview surface once the surfaceCreated() method is called because at this point the surface will be created and initialized properly.

Now we have to set the appropriate parameters to start the camera using the Camera.Parameters class. We can get the current camera parameter using the getParameters() method of the Camera class. We set the camera parameter once the surfaceChaneged() method is called. Once we set all the camera parameters we can start preview using Camera.startPreview() method. This will start the live preview.

The Camera class uses different callback interface to report different events to the application. The following callback interfaces are used to notify the events;

Camera.AutoFocusCallback
Camera.ErrorCallback
Camera.PictureCallback
Camera.PreviewCallback
Camera.ShutterCallback

The Camera.AutoFocusCallback interface is used to notify the completion of auto focus. Note that all devices may not have auto-focus feature. The onAutoFocus() will be called once the auto focus in finished. We use Camera.autoFocus() method to start the auto focus.

The Camera.ErrorCallback interface is used to notify when an error occurred. The onError() method will be called if an error occurred during the camera operation.

The Camera.PictureCallback interface is used to supply the image data after the picture is taken. The onPictureTaken() method will be called once the data is available. The format of the data depends on the current camera picture format which can be set using Camera.Parameters class.

The Camera.PreviewCallback interface is used to notify the supply the current preview frame. The onPreviewFrame() method will be called when the preview frame is available. Again the format of the data depends on the current camera picture format.

The Camera.ShutterCallback interface is to notify when the picture is captured from the camera. The onShutter() method will be called once the picture is taken from the camera.

To take a still picture, we use the method Camera.takePicture() The takePicture() method has three parameters. First one is a Camera.ShutterCallback interface to notify when the picture is captured from the camera. Second one is Camera.PictureCallback interface to notify when raw data is available from the camera. The third one is another Camera.PictureCallback interface when the JPEG data is available from the device.

In API version 5 or above there is another variant of takePicture() method. This method accepts 4 parameters. The first and second are same as the previous one. The third is the Camera.PictureCallback interface which is used to notify when completely scaled postview image is available. The forth one is the same as the third parameter in the first variant.

The data will be supplied to the calling application, the application can use this data for post processing or saving to a file.

In API version 8 or above, we can use the method Camera.setDisplayOrientation() method to set the orientation of the display. This is used by portrait applications to correctly display the live preview. In versions prior to 8, we can safely use the landscape mode to correctly display the preview.

The sample application displays the live preview. When the take picture button is clicked the image is saved to sdcard using time as the filename.

Happy Camera Coding 🙂

9 Comments

Add yours →

  1. Hello I think your website is a good read! I found it on bing. Will make sure to come back soon.

    • Thank you Andrew, I do blog during weekends and will make sure that there will more interesting articles. Currently working on Image Processing in Android, not a complete one but a small application that includes basic image filters and all. Please express your ideas here.

  2. Seriously happy i stumbled upon this excellent website, will make sure to book mark it so i can visit regularly.

    • Thank you, I do blog during weekends and will make sure that there will more interesting articles. Currently working on Image Processing in Android, not a complete one but a small application that includes basic image filters and all. Please express your ideas here.

  3. iam new to android development.tried your source code.it is giving error everywhere when viewbyid is used saying id cannot be resolved to a field.

  4. Can anyone help me? I’ve got some code (see http://james-bennet.com/?p=122). The activities-based way works, but using the Camera API doesnt. What am I doing wrong?

  5. I think this is a wonderful blog. I am going to do a project for My MSC in Andriod . I this will helpful me.

  6. Dear Mr. Verma,

    I want to stream RGB from the Camera. This can be done in 2 ways:

    1) Mobile Hardware Programming.
    2) By somehow automating snapshots from the Camera and capturing those images.(This could of course result in a small frame rate).

    Please tell me which mobile to purchase if I am to achieve objective 1. What are the sdk, RAM and processor requirements for the mobile. If possible, please suggest a mobile brand which I could purchase.

    If I am to achieve objective 2, tell me how to automate a snapshot of the camera app by software.

    Some help would be appreciated. Thanx in advance.

  7. Vincenzo ugolino arieta

    October 28, 2015 — 5:50 pm

    Hi Krishnaraj Varma, congratulations for your good website. I’m developping an android application using opencv. I’d like to know if the input frame of onCameraFrame (CvCameraViewListener frame) method is retrieved only after the camera focus process is finished, or it could be taken in the middle of focus scanning?
    Thank you in advance and sorry for my bad english

Leave a Reply