要在Android中调用相机功能,一是调用系统相机,二是利用Camera与SurfaceView进行处理。而我的问题是使用第二种方法,拍照时系统无反应,具体描述如下:
现象描述:
魅族mx2上,点击拍照,没有反应!!
魅族MX2明明我是测试过可以用的,但是第二天同事测得时候发现了这个问题,思来想去的找不到办法,这到底是什么原因呢,我把工程clean了好几遍,程序也卸载了重装仍然不见效。之后只有代码调试了,发现在调用mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);方法进行拍照后,系统竟未调用jpegCallback回调方法。这是为什么呢?
原因分析:
因为一部分手机(如:note2)在拍照后,SurfaceView很快就回到了预览状态,这和手机系统有关,我想让相机拍照后,将图片显示在SurfaceView上,也就是让SurfaceView停止预览。于是就将拍照所得的图片设置成SurfaceView的背景,这样就达到了效果。但是这样一来就出现了一个问题,预览图与设置为背景的图片,有些变形。为了使预览图不变形,将PictureSize与PreviewSize的值设置为相同相同的值,但是设置的PictureSize是不被其支持的Size,因此造成了拍照后不调用此回调方法的bug。
解决方法:
获取受支持的Size进行设置,方法如下:
总结:
也许其他型号的手机也会出现这样的问题,不出现问题只不过是碰巧设置的PictureSize与PreviewSize是两个都支持的Size而已。
现象描述:
魅族mx2上,点击拍照,没有反应!!
魅族MX2明明我是测试过可以用的,但是第二天同事测得时候发现了这个问题,思来想去的找不到办法,这到底是什么原因呢,我把工程clean了好几遍,程序也卸载了重装仍然不见效。之后只有代码调试了,发现在调用mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);方法进行拍照后,系统竟未调用jpegCallback回调方法。这是为什么呢?
原因分析:
因为一部分手机(如:note2)在拍照后,SurfaceView很快就回到了预览状态,这和手机系统有关,我想让相机拍照后,将图片显示在SurfaceView上,也就是让SurfaceView停止预览。于是就将拍照所得的图片设置成SurfaceView的背景,这样就达到了效果。但是这样一来就出现了一个问题,预览图与设置为背景的图片,有些变形。为了使预览图不变形,将PictureSize与PreviewSize的值设置为相同相同的值,但是设置的PictureSize是不被其支持的Size,因此造成了拍照后不调用此回调方法的bug。
解决方法:
获取受支持的Size进行设置,方法如下:
- /* 相机初始化的method */
- private void initCamera() {
- if (mCamera != null) {
- try {
- Camera.Parameters parameters = mCamera.getParameters();
- parameters.setPictureFormat(PixelFormat.JPEG);
- //设置被支持的预览界面与图片的size
- List<size> previewSizes = parameters.getSupportedPreviewSizes();
- Size size = getCurrentScreenSize(previewSizes, 1);
- parameters.setPreviewSize(size.width, size.height);
- // 这里就是错误的所在,因为设置的size不一定是PictureSize所支持的
- // parameters.setPictureSize(size.width, size.height);
- List<size> pictureSizes = parameters.getSupportedPictureSizes();
- Size size2 = getCurrentScreenSize(pictureSizes, 1);
- parameters.setPictureSize(size2.width, size2.height);
- mCamera.setParameters(parameters);
- /* 开启预览画面 */
- mCamera.startPreview();
- } catch (Exception e) {
- e.printStackTrace();
- }
- mAutoFocusCallback.setHandler(mainHandler, 1);
- try {
- mCamera.autoFocus(mAutoFocusCallback);
- } catch (Exception exception) {
- exception.printStackTrace();
- }
- }
- }
- /**
- * 获得最接近频幕宽度的尺寸
- *
- * @param sizeList
- * @param n
- * 放大几倍 (>0)
- * @return
- */
- private Size getCurrentScreenSize(List<size> sizeList, int n) {
- if (sizeList != null && sizeList.size() > 0) {
- int screenWidth = ViewUtil.getScreenWidth(this) * n;
- int[] arry = new int[sizeList.size()];
- int temp = 0;
- for (Size size : sizeList) {
- arry[temp++] = Math.abs(size.width - screenWidth);
- }
- temp = 0;
- int index = 0;
- for (int i = 0; i < arry.length; i++) {
- if (i == 0) {
- temp = arry[i];
- index = 0;
- } else {
- if (arry[i] < temp) {
- index = i;
- temp = arry[i];
- }
- }
- }
- return sizeList.get(index);
- }
- return null;
- }
- </size></size></size>
总结:
也许其他型号的手机也会出现这样的问题,不出现问题只不过是碰巧设置的PictureSize与PreviewSize是两个都支持的Size而已。
为了修改一个错误,而造成另外一个错误,大概是每个程序员都会犯的错。这不仅仅是因为自己对API的理解的不够透彻,而且是一个人的态度问题,以后要多加认真才是。
http://blog.youkuaiyun.com/wangfayinn/article/details/9319161