This article translated from: http://developer.android.com/training/camera/cameradirect.html
In this article, we will discuss how to use the framework API to directly control camera hardware.
Directly controlling cameras such as devices requires more encoding than obtaining images or videos from existing Camera applications. However, if you want to create a special camera application or fully integrate with your application UI, this article will show you how to do it.
Open a camera object
Directly control the camera's first step to get a camera object instance. Like the android camera application, we recommend that you access the camera by enabling an independent thread from the oncreate () callback of the activity to open the camera object. This is a good practice, because it takes some time to open the camera object, which may block the UI thread. A more basic implementation of the camera can be delayed to the onresume () callback method, which facilitates code reuse and maintains a simple control flow.
If the camera has been used by other applications, an exception will be thrown when you call the camera. open () method... Catch Block.
Privatebooleansafecameraopen (int
ID ){
Boolean qopened = false;
Try {
Releasecameraandpreview ();
Mcamera = camera. Open (ID );
Qopened = (mcamera! = NULL );
} Catch (exception e ){
Log. E (getstring (R. String. app_name), "failed to open camera ");
E. printstacktrace ();
}
Return qopened;
}
Private void releasecameraandpreview (){
Mpreview. setcamera (null );
If (mcamera! = NULL ){
Mcamera. Release ();
Mcamera = NULL;
}
}
Since API level 9, the camera framework supports multiple cameras. If you use a traditional API and call the open () method without parameters, you will get the rear camera.
Create a camera Preview
You usually need to preview the image before clicking the shutter to take a photo. Therefore, you can use surfaceview to depict the image captured by the camera.
Create preview class
To display the preview image, you need to create a preview class to implement the Android. View. surfaceholder. Callback interface, which is used to transmit the image data of the camera hardware to the application.
Classpreviewextendsviewgroupimplementssurfaceholder. Callback {
Surfaceview msurfaceview;
Surfaceholder mholder;
Preview (context ){
Super (context );
Msurfaceview = new surfaceview (context );
Addview (msurfaceview );
// Install asurfaceholder. Callback so we get notified when
// Underlying surface is created and destroyed.
Mholder = msurfaceview. getholder ();
Mholder. addcallback (this );
Mholder. settype (surfaceholder. surface_type_push_buffers );
}
...
}
This preview class must be passed to the camera object before displaying the preview image.
Set and start image Preview
A camera instance and Its Related previews must be created in a specific order. The first step is to create a camera object. The following code snippet encapsulates the camera initialization process so that you can call the camera. startpreviw () method by using the setcamera () method whenever you change the camera. This preview class must also be restarted in the surfacechanged () callback method of the preview class.
Publicvoidsetcamera (Camera
Camera ){
If (mcamera = camera) {return ;}
Stoppreviewandfreecamera ();
Mcamera = camera;
If (mcamera! = NULL ){
List <size> localsizes = mcamera. getparameters (). getsupportedpreviewsizes ();
Msupportedpreviewsizes = localsizes;
Requestlayout ();
Try {
Mcamera. setpreviewdisplay (mholder );
} Catch (ioexception e ){
E. printstacktrace ();
}
/*
Important: callstartpreview () to start updating the preview surface. Preview must
Be started before you cantake a picture.
*/
Mcamera. startpreview ();
}
}
Modify camera settings
The camera settings change the way the camera is taken, from zoom level to exposure. This example only changes the preview size. For more settings, see the source code of the camera application.
Publicvoidsurfacechanged (surfaceholder
Holder, int format, int W, int
H ){
// Now that the size isknown, set up the camera parameters and begin
// The preview.
Camera. parameters = mcamera. getparameters ();
Parameters. setpreviewsize (mpreviewsize. Width, mpreviewsize. Height );
Requestlayout ();
Mcamera. setparameters (parameters );
/*
Important: Call startpreview () to startupdating the preview surface. Preview must be
Started before you can take a picture.
*/
Mcamera. startpreview ();
}
Set preview direction
Most camera applications lock the display in Landscape mode because it is the natural direction of the camera. This setting does not prevent you from taking portrait photos because the device direction is recorded in the EXIF header. Using the setcameradisplayorientation () method changes the Preview display mode without affecting the recorded image. However, for Android versions earlier than API Level 14, you must terminate the preview before restarting the SDK.
Photograph
After image preview is started, you can use the camera. takepicture () method to take a photo. You can create camera. picturecallback and camera. shuttercallback objects and pass them to the camera. takepicture () method.
If you want to continuously capture images, you can create a camera. previewcallback interface that implements the onpreviewframe () method. In this method, you can select only the preview frame to take a picture, or create a delayed action to call the takepicture () method.
Restart Preview
After taking a photo, you must restart the image preview before the user can continue taking the photo. In the following example, the shutter button is used to restart the image preview.
@ Override
Public void onclick (view v ){
Switch (mpreviewstate ){
Case k_state_frozen:
Mcamera. startpreview ();
Mpreviewstate = k_state_preview;
Break;
Default:
Mcamera. takepicture (null, rawcallback, null );
Mpreviewstate = k_state_busy;
} // Switch
Shutterbtnconfig ();
}
Terminate preview and release the camera object
Once your application uses the camera, it is time to clean up. In particular, you must release the camera object. Otherwise, other applications may crash, including new instances of your own applications.
When will the preview be terminated and the camera object be released? When the image preview class is destroyed, it is a good time to stop the image preview and release the camera object. For example:
Publicvoidsurfacedestroyed (surfaceholder
Holder ){
// Surface will bedestroyed when we return, so stop the preview.
If (mcamera! = NULL ){
/*
Call stoppreview () to stopupdating the preview surface.
*/
Mcamera. stoppreview ();
}
}
/**
* When this function returns, mcamera will be null.
*/
Private void stoppreviewandfreecamera (){
If (mcamera! = NULL ){
/*
Call stoppreview () to stopupdating the preview surface.
*/
Mcamera. stoppreview ();
/*
Important: Call release () torelease the camera for use by other applications.
Applications shocould releasethe camera immediately in onpause () (and re-open () it in
Onresume ()).
*/
Mcamera. Release ();
Mcamera = NULL;
}
}