要在Android中调用相机功能,一是调用系统相机,二是利用Camera与SurfaceView进行处理。而我的问题是使用第二种方法,拍照时系统无反应,具体描述如下:
现象描述:
魅族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
  
  
   
    previewSizes = parameters.getSupportedPreviewSizes();
				
				Size size = getCurrentScreenSize(previewSizes, 1);
				parameters.setPreviewSize(size.width, size.height);
				
//			这里就是错误的所在,因为设置的size不一定是PictureSize所支持的
//			parameters.setPictureSize(size.width, size.height);


				List
   
   
    
     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
    
    
     
      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;
	}





总结:


也许其他型号的手机也会出现这样的问题,不出现问题只不过是碰巧设置的PictureSize与PreviewSize是两个都支持的Size而已。


为了修改一个错误,而造成另外一个错误,大概是每个程序员都会犯的错。这不仅仅是因为自己对API的理解的不够透彻,而且是一个人的态度问题,以后要多加认真才是。