1. 程式人生 > >java.lang.RuntimeException: autoFocus failed,Call autoFocus when preview is inactive (state = 1)

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

java.lang.RuntimeException: autoFocus failed

在使用華為手機測試自定義相機時,一進入自定義相機介面就崩潰,異常log資訊如上。其他測試機沒這個問題。

程式碼如下:

private void doStartPreview() {
        try {
            if (mCamera != null) {
                width = mSurfaceView.getMeasuredWidth();
                height = mSurfaceView.getMeasuredHeight();
                Log.e(TAG, "寬高:" + width + "," + height + ",mCamera:" + mCamera);
                mParams = mCamera.getParameters();

                if (screenProp == 0) {
                    screenProp = (float) height / (float) width;
                    Log.e(TAG, "screenProp:" + screenProp + "," + height + width);
                }

                previewSize = CameraParamUtil.getInstance().getPreviewSize(mParams
                        .getSupportedPreviewSizes(), 1000, screenProp);
                pictureSize = CameraParamUtil.getInstance().getPictureSize(mParams
                        .getSupportedPictureSizes(), 1200, screenProp);

                mParams.setPreviewSize(previewSize.width, previewSize.height);
                mParams.setPictureSize(pictureSize.width, pictureSize.height);
                Log.e(TAG, "previewSize:" + previewSize.width + previewSize.height + ",pictureSize:" + pictureSize.width + pictureSize.height);
                if (CameraParamUtil.getInstance().isSupportedFocusMode(
                        mParams.getSupportedFocusModes(),
                        Camera.Parameters.FOCUS_MODE_AUTO)) {
                    mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                }
                if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParams.getSupportedPictureFormats(),
                        ImageFormat.JPEG)) {
                    mParams.setPictureFormat(ImageFormat.JPEG);
                    mParams.setJpegQuality(100);
                }

                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//自動對焦
                mCamera.setParameters(mParams);
                mCamera.setPreviewDisplay(mSurfaceHolder);
                mCamera.setDisplayOrientation(cameraAngle);//瀏覽角度
//                mCamera.setPreviewCallback(this); //每一幀回撥。這個要註釋掉,否則會出現Camera is being used after Camera.release() was called異常
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        camera.cancelAutoFocus();
                    }
                });
		mCamera.startPreview();//開始預覽
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

還沒有預覽就進行對焦是不行的。把startPreview放在autoFocus前面。

修改如下:

 // 自動對焦
 //                mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);//註釋掉
                mCamera.setParameters(mParams);
                mCamera.setPreviewDisplay(mSurfaceHolder);
                mCamera.setDisplayOrientation(cameraAngle);//瀏覽角度
 //                mCamera.setPreviewCallback(this); //每一幀回撥。這個要註釋掉,否則會出現Camera is being used after Camera.release() was called異常
                mCamera.startPreview();//開始預覽
                //自動對焦。要放在startPreview後面,否則可能報自動對焦失敗異常,還沒預覽就進行對焦是不行的。
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        camera.cancelAutoFocus();
                    }
                });

執行正常。

但是如果點選了拍照按鈕,preview停止了活動,如果點選“確定”和“取消”按鈕之外的區域,頁面出現異常。當然這個也是華為手機出現的問題,其他測試機沒有出現。

檢視log:

Call autoFocus when preview is inactive (state = 1)
preview停止活動時呼叫了autoFocus方法。異常程式碼如下:
 @Override
    public boolean onTouchEvent(MotionEvent event) {
        //對焦
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                camera.cancelAutoFocus();
            }
        });
        return super.onTouchEvent(event);
    }

點選螢幕時呼叫autoFocus方法,自動對焦。

那就在preview活動時再呼叫autoFocus。但是怎麼判斷preview是活動的呢?目前只有mCamera.stopPreview()、mCamera.startPreview()方法表明是否是活動的,沒找到其他可以判斷是否活動的方法。後來想了想,設定一個boolean值isPreviewActive判斷是否活動。當mCamera.stopPreview()時isPreviewActive=false;當mCamera.startPreview()時isPreviewActive=true。

程式碼如下:

    private boolean isPreviewActive=true;//preview是否是活動的。防止preview是inactive時去呼叫對焦產生異常。
   
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(isPreviewActive) {//preview活動時才能呼叫自動對焦功能
            //對焦
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    camera.cancelAutoFocus();
                }
            });
        }
        return super.onTouchEvent(event);
    }
問題解決。