最近项目中遇到在连续拍照时出现take picture failed,在排除各种权限以及正常的问题后,打log后发现是因为在连续takePicture(null, null, jpeg)时,上一次拍照还没有来得及回调,又执行了takePicture导致take picture failed。
解决办法 : 在takePicture后,如果还没有回调,但是又有拍照任务进来,就把这个任务放进队列,在回调之后执行这个队列。
private List<Integer> mWaitAction = new LinkedList<>(); //暂存拍照的队列
private boolean isTaking = false; //是否处于拍照中
.......省略各种Camera初始化代码
public void takePicture() { //对外暴露的方法,连续拍照时调用
if (isTaking) { //判断是否处于拍照,如果正在拍照,则将请求放入缓存队列
mWaitAction.add(1);
} else {
doTakeAction();
}}
private void doTakeAction() { //拍照方法
isTaking = true;
mCamera.takePicture(null, null, jpeg);
}
//创建JPEG图片后回调
private Camera.PictureCallback jpeg = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
if (mWaitAction.size() > 0) {
mWaitAction.remove(0); //移除队列中的第一条拍照请求,并执行拍照请求
mHandler.sendEmptyMessage(0); //主线程中调用拍照
} else { //队列中没有拍照请求,走正常流程
isTaking = false;
}
new SavePictureTask().execute(data); //异步保存照片
mCamera.startPreview(); //如果不调用 ,则画面不会更新
}};
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
doTakeAction();
}
};
public class SavePictureTask extends AsyncTask<byte[], String, String> {
@SuppressLint("SimpleDateFormat")
@Override
protected String doInBackground(byte[]... params) {
byte[] data = params[0]; //回调的数据
........省略保存图片
}
return null;
}
}
网友评论