android10

  • Increase font size
  • Default font size
  • Decrease font size

Using Camera API in Android

E-mail Print
( 5 Votes )
Share

Introduction

Android SDK supports the connectivity to the built-in camera. Using the camera to take photos is relatively easy. It is somewhat harder to setup the camera preview to work properly.

using_camera_api_00



Using the Camera API

In our main activity, we create the Preview object. This object will create the Camera object and return it to the CameraDemo activity.

Next we register couple of call-back method with the Camera to be performed when the user takes a photo.

shutterCallback is called when the shutter is opened and picture is taken. rawCallback and jpegCallback will get the data for the raw and jpeg encoding of the photo. It's up to you to do something with this data, such as save it to the SD card.

CameraDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.example;
 
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
 
public class CameraDemo extends Activity {
private static final String TAG = "CameraDemo";
Camera camera;
Preview preview;
Button buttonClick;
 
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
 
preview = new Preview(this);
((FrameLayout) findViewById(R.id.preview)).addView(preview);
 
buttonClick = (Button) findViewById(R.id.buttonClick);
buttonClick.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
preview.camera.takePicture(shutterCallback, rawCallback,
jpegCallback);
}
});
 
Log.d(TAG, "onCreate'd");
}
 
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
Log.d(TAG, "onShutter'd");
}
};
 
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken - raw");
}
};
 
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
// write to local sandbox file system
// outStream =
// CameraDemo.this.openFileOutput(String.format("%d.jpg",
// System.currentTimeMillis()), 0);
// Or write to sdcard
outStream = new FileOutputStream(String.format(
"/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpeg");
}
};
 
}

Preview class handles the preview from the camera. It subclasses SurfaceView class so that it can be placed in the UI itself. It also implements the SurfaceHolder.Callback interface so it gets the callbacks when the UI becomes available.

Preview.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.example;
 
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
class Preview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "Preview";
 
SurfaceHolder mHolder;
public Camera camera;
 
Preview(Context context) {
super(context);
 
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
 
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where
// to draw.
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
 
camera.setPreviewCallback(new PreviewCallback() {
 
public void onPreviewFrame(byte[] data, Camera arg1) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format(
"/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d(TAG, "onPreviewFrame - wrote bytes: "
+ data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Preview.this.invalidate();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
 
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
camera.stopPreview();
camera = null;
}
 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
camera.startPreview();
}
 
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
Paint p = new Paint(Color.RED);
Log.d(TAG, "draw");
canvas.drawText("PREVIEW", canvas.getWidth() / 2,
canvas.getHeight() / 2, p);
}
}

The layout is fairly straight forward. We have the FrameLayout as the placeholder for the Preview to be attached to. This is done programmatically in CameraDemo.onCreate().

/res/layout/main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:id="@+id/layout">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Camera Demo"
android:textSize="24sp" />
 
<FrameLayout android:id="@+id/preview"
android:layout_weight="1" android:layout_width="fill_parent"
android:layout_height="fill_parent">
</FrameLayout>
 
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonClick"
android:text="Click" android:layout_gravity="center"></Button>
 
</LinearLayout>
 

And finally remember to add <uses-permission android:name="android.permission.CAMERA" /> to your AndroidManifest.xml file.

The final app looks like this:

using_camera_api_01

You can find the source code of this example below. Thanks marakana for this amazing article!!!

Source code files
FileDescriptionSDK VersionFile sizeLast Modified
Download this file (CameraDemo.zip)CameraDemo.zipThe source code for this example436 Kb25/01/11 22:24
Comments (8)
  • prashanth

    y is the application force close when i hold the device in landscape alignment. ?

  • penano
    avatar

    You shouldn't have the FC, because we are just forcing the application to be in vertical mode.

    android:orientation="vertical"

    :)

  • tej

    When I held the device in landscape mode, the application is force closed inspite of
    android:orientation="vertical".

    Also while taking the picture, even thouth the object is held in horizontal position, the picture is taken vertically. Plz tell me why?

  • terrychan04

    When i using eclipse connect to my android phone(MOTOROLA DEFY) to run, i forced to close.

  • Badams  - re:
    penano wrote:
    You shouldn't have the FC, because we are just forcing the application to be in vertical mode.

    android:orientation="vertical"

    :)

    penano,
    Your advice is incorrect.
    android:orientation="vertical" applies to the linear layout and nothing to do with the device orientation.

    To force the application to run in Portrait mode, you need to add the following into your Android Manifest for your activity:

    android:screenOrientation="portrait"

  • hanif_2710

    it gives me error your project contains error(s),please fix them before running your application
    please guide me

  • karan123

    hey plz guide me.......
    when i try to run this the application closes down unexpetedly ,what can be reason for that!!!!!!!!!!!!

Only registered users can write comments!
 

ANDROID10 --- TIP!!!

android10 tipIf you are writing an article and want to include your source code or a file...is pretty simple: first you save your article for first time to create it, then you edit it and at bottom of the editor, you have a button "Add Attachment"...just click it, upload your file...and that's all...too easy...
contact android10!!!