直接控制硬件需要比使用相机应用使用更多的代码来实现。但为了实现特定的应用和将一些功能完全的集成到你的应用程序中,你必须要这么做。
1.打开相机对象。
首先需要获得Camera对象实例。就像Android自身的相机应用一样,在OnCreate()方法中,建立新的线程来代开Camera。我们经常在OnResume()方法中实现,在OnResume()方法中实现的好处是使代码可以被在次使用和简化控制流。调用Camera.open(),如果Camera已经在使用,就抛出一个异常:
private boolean safeCameraOpen(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;
}
}
2.创建相机预览。在拍照之前,我们需要提供预览功能,这个功能由SurfaceView实现。
为了实现预览,我们需要实现android.view.SurfaceHolder.Callback接口,它是用来从相机硬件来传递图片的。
class Preview
extends ViewGroup
implements SurfaceHolder.Callback
{
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
Preview(Context context)
{
super(context);
mSurfaceView = new
SurfaceView(context);
addView(mSurfaceView);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
...
}
设置和开启预览。在开始预览之前,我们必须要将预览类传递给camera对象。
public void setCamera(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: Call startPreview() to start updating the preview surface. Preview must
be started before you can take a picture.
*/
mCamera.startPreview();
}
}
修改相机设置。下面代码是预览大小的设置代码:
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
= mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
mCamera.setParameters(parameters);
/*
Important: Call startPreview() to start updating the preview surface. Preview must be
started before you can take a picture.
*/
mCamera.startPreview();
}
使用setCameraDisplayOrientation()设置相机显示的方向。使用Camera.takePicture()来拍照。
重新预览:
@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();
}
停止预览释放相机:
public void surfaceDestroyed(SurfaceHolder holder)
{
// Surface will be destroyed when we return, so stop the preview.
if (mCamera
!= null)
{
/*
Call stopPreview() to stop updating the preview surface.
*/
mCamera.stopPreview();
}
}
/**
* When this function returns, mCamera will be null.
*/
private void stopPreviewAndFreeCamera()
{
if (mCamera
!= null)
{
/*
Call stopPreview() to stop updating the preview surface.
*/
mCamera.stopPreview();
/*
Important: Call release() to release the camera for use by other applications.
Applications should release the camera immediately in onPause() (and re-open() it in
onResume()).
*/
mCamera.release();
mCamera = null;
}
}