java.lang.RuntimeException: autoFocus failed,Call autoFocus when preview is inactive (state = 1)

[java] view plain copy

  1. java.lang.RuntimeException: autoFocus failed

在使用华为手机测试自定义相机时,一进入自定义相机界面就崩溃,异常log信息如上。其他测试机没这个问题。

代码如下:

  1. private void doStartPreview() {
  2.         try {
  3.             if (mCamera != null) {
  4.                 width = mSurfaceView.getMeasuredWidth();
  5.                 height = mSurfaceView.getMeasuredHeight();
  6.                 Log.e(TAG, “宽高:” + width + “,” + height + “,mCamera:” + mCamera);
  7.                 mParams = mCamera.getParameters();
  8.                 if (screenProp == 0) {
  9.                     screenProp = (float) height / (float) width;
  10.                     Log.e(TAG, “screenProp:” + screenProp + “,” + height + width);
  11.                 }
  12.                 previewSize = CameraParamUtil.getInstance().getPreviewSize(mParams
  13.                         .getSupportedPreviewSizes(), 1000, screenProp);
  14.                 pictureSize = CameraParamUtil.getInstance().getPictureSize(mParams
  15.                         .getSupportedPictureSizes(), 1200, screenProp);
  16.                 mParams.setPreviewSize(previewSize.width, previewSize.height);
  17.                 mParams.setPictureSize(pictureSize.width, pictureSize.height);
  18.                 Log.e(TAG, “previewSize:” + previewSize.width + previewSize.height + “,pictureSize:” + pictureSize.width + pictureSize.height);
  19.                 if (CameraParamUtil.getInstance().isSupportedFocusMode(
  20.                         mParams.getSupportedFocusModes(),
  21.                         Camera.Parameters.FOCUS_MODE_AUTO)) {
  22.                     mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
  23.                 }
  24.                 if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParams.getSupportedPictureFormats(),
  25.                         ImageFormat.JPEG)) {
  26.                     mParams.setPictureFormat(ImageFormat.JPEG);
  27.                     mParams.setJpegQuality(100);
  28.                 }
  29.                 mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//自动对焦
  30.                 mCamera.setParameters(mParams);
  31.                 mCamera.setPreviewDisplay(mSurfaceHolder);
  32.                 mCamera.setDisplayOrientation(cameraAngle);//浏览角度
  33. //                mCamera.setPreviewCallback(this); //每一帧回调。这个要注释掉,否则会出现Camera is being used after Camera.release() was called异常
  34.                 mCamera.autoFocus(new Camera.AutoFocusCallback() {
  35.                     @Override
  36.                     public void onAutoFocus(boolean success, Camera camera) {
  37.                         camera.cancelAutoFocus();
  38.                     }
  39.                 });
  40.         mCamera.startPreview();//开始预览
  41.             }
  42.         } catch (IOException e) {
  43.             e.printStackTrace();
  44.         }
  45.     }

还没有预览就进行对焦是不行的。把startPreview放在autoFocus前面。

修改如下:

  1. // 自动对焦
  2. //                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//注释掉
  3.                mCamera.setParameters(mParams);
  4.                mCamera.setPreviewDisplay(mSurfaceHolder);
  5.                mCamera.setDisplayOrientation(cameraAngle);//浏览角度
  6. //                mCamera.setPreviewCallback(this); //每一帧回调。这个要注释掉,否则会出现Camera is being used after Camera.release() was called异常
  7.                mCamera.startPreview();//开始预览
  8.                //自动对焦。要放在startPreview后面,否则可能报自动对焦失败异常,还没预览就进行对焦是不行的。
  9.                mCamera.autoFocus(new Camera.AutoFocusCallback() {
  10.                    @Override
  11.                    public void onAutoFocus(boolean success, Camera camera) {
  12.                        camera.cancelAutoFocus();
  13.                    }
  14.                });

运行正常。

但是如果点击了拍照按钮,preview停止了活动,如果点击“确定”和“取消”按钮之外的区域,页面出现异常。当然这个也是华为手机出现的问题,其他测试机没有出现。

查看log:

  1. Call autoFocus when preview is inactive (state = 1)

preview停止活动时调用了autoFocus方法。异常代码如下:

  1. @Override
  2.    public boolean onTouchEvent(MotionEvent event) {
  3.        //对焦
  4.        mCamera.autoFocus(new Camera.AutoFocusCallback() {
  5.            @Override
  6.            public void onAutoFocus(boolean success, Camera camera) {
  7.                camera.cancelAutoFocus();
  8.            }
  9.        });
  10.        return super.onTouchEvent(event);
  11.    }

点击屏幕时调用autoFocus方法,自动对焦。

那就在preview活动时再调用autoFocus。但是怎么判断preview是活动的呢?目前只有mCamera.stopPreview()、mCamera.startPreview()方法表明是否是活动的,没找到其他可以判断是否活动的方法。后来想了想,设置一个boolean值isPreviewActive判断是否活动。当mCamera.stopPreview()时isPreviewActive=false;当mCamera.startPreview()时isPreviewActive=true。

代码如下:

  1. private boolean isPreviewActive=true;//preview是否是活动的。防止preview是inactive时去调用对焦产生异常。
  2. @Override
  3. public boolean onTouchEvent(MotionEvent event) {
  4.     if(isPreviewActive) {//preview活动时才能调用自动对焦功能
  5.         //对焦
  6.         mCamera.autoFocus(new Camera.AutoFocusCallback() {
  7.             @Override
  8.             public void onAutoFocus(boolean success, Camera camera) {
  9.                 camera.cancelAutoFocus();
  10.             }
  11.         });
  12.     }
  13.     return super.onTouchEvent(event);
  14. }

问题解决。

发表评论

电子邮件地址不会被公开。 必填项已用*标注