本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结。由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2。
文档中的Camera
要使用Camera,首先我们先看一下文档(http://androiddoc.qiniudn.com/reference/android/hardware/Camera.html)中是怎么介绍的。相对于其他绝大多数类,文档对Camera的介绍还是比较详尽的,包含了使用过程中所需要的步骤说明,当然,这也表明了它在实际使用中的繁琐。
首先,需要在AndroidManifest.xml
中声明以下权限和特性:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
然后,拍照的话,需要以下十步:
1. 通过open(int)
方法得到一个实例
2. 通过getParameters()
方法得到默认的设置
3. 如果有必要,修改上面所返回的Camera.Parameters
对象,并调用setParameters(Camera.Parameters)
进行设置
4. 如果有需要,调用setDisplayOrientation(int)
设置显示的方向
5. 这一步很重要,通过setPreviewDisplay(SurfaceHolder)
传入一个已经初始化了的SurfaceHolder
,否则无法进行预览。
6. 这一步也很重要,通过startPreview()
开始更新你的预览界面,在你拍照之前,它必须开始。
7. 调用takePicture(Camera.ShutterCallback, Camera.PictureCallback, Camera.PictureCallback, Camera.PictureCallback)
进行拍照,等待它的回调
8. 拍照之后,预览的展示会停止。如果想继续拍照,需要先再调用startPreview()
。
9. 调用stopPreview()
停止预览。
10. 非常重要,调用release()
释放Camera,以使其他应用也能够使用相机。你的应用应该在onPause()
被调用时就进行释放,在onResume()
时再重新open()
。
上面就是文档中关于使用Camera进行拍照的介绍了。接下来说一下我的使用场景。
我的使用场景
这是项目的界面需求。下面一个圆的拍照按钮,然后是一个取消按钮,上面是预览界面(SurfaceView)加个取景框。再上面就是一块黑的了。点拍照,拍照之后,跳到一个裁剪图片的界面,所以不会有连续拍多次照片的场景。
取景框什么的这里略过不谈,布局文件也相对比较简单,下面直接看Java代码里对Camera的使用。
实际使用及填坑
SurfaceHolder的回调
我在Activity中实现SurfaceHolder.Callback
接口。然后在onCreate(Bundle)
方法中,添加SurfaceHolder
的回调。
SurfaceHolder holder = mSurfaceView.getHolder();
holder.addCallback(this);
它的回调方法有3个,分别是surface被创建时的回调surfaceCreated(SurfaceHolder)
,surface被销毁时的回调surfaceDestroyed(SurfaceHolder)
以及surface改变时的回调surfaceChanged(SurfaceHolder holder, int, int, int)
。这里我们只关注创建和销毁时的回调,定义一个变量用于标志它的状态。
private boolean mIsSurfaceReady;
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsSurfaceReady = true;
startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsSurfaceReady = false;
}
其中的startPreview()方法将在下面讲到。
打开相机
然后是打开相机。这些代码在我定义的openCamera
方法中。
if (mCamera == null) {