获取到 Camera 对象是直接控制Camera的第一步。正如Android自带的相机程序一样,推荐访问Camera的方式是在onCreate方法里面另起一个Thread来打开Camera。这个方法可以避免因为打开工作比较费时而引起ANR。在一个更加基础的实现方法里面,打开Camera的动作被延迟到onResume()方法里面去执行,这样使得代码能够更好的重用,并且保持控制流程不会复杂化。(原文是:In a more basic implementation, opening the camera can be deferred to the onResume() method to facilitate code reuse and keep the flow of control simple.)
privatebooleansafeCameraOpen(intid){booleanqOpened=false;try{releaseCameraAndPreview();mCamera=Camera.open(id);qOpened=(mCamera!=null);}catch(Exceptione){Log.e(getString(R.string.app_name),"failed to open Camera");e.printStackTrace();}returnqOpened;}privatevoidreleaseCameraAndPreview(){mPreview.setCamera(null);if(mCamera!=null){mCamera.release();mCamera=null;}}
classPreviewextendsViewGroupimplementsSurfaceHolder.Callback{SurfaceViewmSurfaceView;SurfaceHoldermHolder;Preview(Contextcontext){super(context);mSurfaceView=newSurfaceView(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);}...}
publicvoidsetCamera(Cameracamera){if(mCamera==camera){return;}stopPreviewAndFreeCamera();mCamera=camera;if(mCamera!=null){List<Size>localSizes=mCamera.getParameters().getSupportedPreviewSizes();mSupportedPreviewSizes=localSizes;requestLayout();try{mCamera.setPreviewDisplay(mHolder);}catch(IOExceptione){e.printStackTrace();}/* Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture. */mCamera.startPreview();}}
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intw,inth){// Now that the size is known, set up the camera parameters and begin// the preview.Camera.Parametersparameters=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();}
Set the Preview Orientation(设置预览方向)
大多数相机程序会锁定预览为横屏的,因为那是人拍照的自然方式。设置里面并没有阻止你去拍竖屏的照片,这些信息会被记录在EXIF里面。 setCameraDisplayOrientation()) 方法可以使得你改变预览的方向,并且不会影响到图片被记录的效果。然而,在Android API level 14之前,你必须在改变方向之前,先停止你的预览,然后才能去重启它。
publicvoidsurfaceDestroyed(SurfaceHolderholder){// 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. */privatevoidstopPreviewAndFreeCamera(){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;}}