Knowpapa.com - a developer's blog

Capture Image using android.hardware module

The android.hardware.camera module provides a direct access to camera API and is the preferred method of taking pictures when you need a finer control over various camera parameters.

The first step involves adding the following to your AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.knowpapa.camerademo" 
.... > 

......

<application 
....
.... > 
<activity 
.........
android:name=".CameraDemoActivity" 
android:screenOrientation = "landscape" 
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 
android:configChanges = "keyboardHidden|orientation"> 
.......
</activity> 
</application> 
<!-- notice the next two lines are outside the application tag -->
<uses-feature android:name="android.hardware.camera" /> 
<uses-permission android:name="android.permission.CAMERA" /> 
</manifest>

For using the camera we first need to implement a SurfaceView, on which the camera preview would render. To do that first create a layout file camerademo.xml and instead of using normal layout like linear layout or relative layout, we use a SurfaceView as follows:

<?xml version="1.0" encoding="utf-8"?> 
<android.view.SurfaceView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/cameraDemo" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" > 
</android.view.SurfaceView>

Next let us define the activity that would actually display the camera:

Remember that you need to import Camera module from the hardware package, not the graphics package, as they are both different classes. The rest of the code should be self explnatory

package com.knowpapa.camerahardware; 
import android.app.Activity; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
public class CameraDemoActivity extends Activity { 
SurfaceView cameraScreen; 
SurfaceHolder previewScreenHolder; 
Camera camera; 
boolean underPreview; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.camerademo); 
underPreview = false; 
cameraScreen = (SurfaceView)findViewById(R.id.cameraDemo); 
previewScreenHolder = cameraScreen.getHolder(); 
previewScreenHolder.addCallback(surfaceCallback); 
previewScreenHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 
@Override 
public void onResume() { 
super.onResume(); 
camera=Camera.open(); 
} 
@Override 
public void onPause() { 
if (underPreview) { 
camera.stopPreview(); 
} 
camera.release(); 
camera=null; 
underPreview=false; 
super.onPause(); 
}
private Camera.Size findbestPreviewSize(int width, int height, 
Camera.Parameters parameters) { 
Camera.Size result=null; 
for (Camera.Size size : parameters.getSupportedPreviewSizes()) { 
if (size.width<=width && size.height<=height) { 
if (result==null) { 
result=size; 
} 
else { 
int resultArea=result.width*result.height; 
int newArea=size.width*size.height; 
if (newArea>resultArea) { 
result=size; 
} 
} 
} 
} 
return(result); 
} 
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() { 
public void surfaceCreated(SurfaceHolder holder) { 
try { 
camera.setPreviewDisplay(previewScreenHolder); 
} 
catch (Throwable t) { 
Log.e(TAG, "Exception in setPreviewDisplay", t); 
} 
} 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
int height) { 
Camera.Parameters parameters=camera.getParameters(); 
Camera.Size size=findbestPreviewSize(width, height, parameters); 
if (size!=null) { 
parameters.setPreviewSize(size.width, size.height); 
camera.setParameters(parameters); 
camera.startPreview(); 
underPreview=true; 
} 
} 
public void surfaceDestroyed(SurfaceHolder holder) { 
// not required 
} 
}; 
}