为什么连续自动对焦摄像头,处理器不要允许切换相机的闪光灯? [英] Why continuous auto focusing camera with handler dont allow to toggle camera flash?

查看:125
本文介绍了为什么连续自动对焦摄像头,处理器不要允许切换相机的闪光灯?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我迄今所做的:

我已实施的自定义相机读取QR code这就需要继续关注的相机更好的QR读取。

我的问题是,当我用专注与处理每一秒钟对\\相机闪光灯关闭按钮不工作或需要太多的时间来打开和关闭相机闪光灯。当我删除的自动对焦摄像头每秒(可运行和处理程序)的code每件事工作正常。

我要的是可自动快速聚焦时相机移动也能打开和关闭对需求的快速闪烁,而无需使用 Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE ,因为它不适用于 API< 14

开始这就是为什么我使用的处理器集中相机时,我已经使用 Camera.Parameters.FOCUS_MODE_AUTO ,但其只关注相机每秒一次。

最小SDK 项目的版本是9。

我的相机是活动

 公共类CameraActivityNew扩展活动实现OnClickListener,
        摄像头。$ P $ {pviewCallback    相机previewNew米preVIEW;
    的FrameLayout flCamera preVIEW;
    的ImageButton ibFlashButton;
    布尔isFlashOn = FALSE;    相机mCamera;    私人处理器mAutoFocusHandler;
    私人布尔米previewing = TRUE;    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        。getWindow()addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        mAutoFocusHandler =新的处理程序();
        的setContentView(R.layout.activity_camera);
        findSetupViews();
        米preVIEW =新相机previewNew(getApplicationContext(),这一点,
                autoFocusCB);
        flCamera preview.addView(M preVIEW);
    }    私人Runnable接口doAutoFocus =新的Runnable(){
        公共无效的run(){
            如果(mCamera = NULL&放大器;!&放,M previewing){
                mCamera.autoFocus(autoFocusCB);
            }
        }
    };
    Camera.AutoFocusCallback autoFocusCB =新Camera.AutoFocusCallback(){
        公共无效onAutoFocus(布尔成功,相机摄像头){
            mAutoFocusHandler.postDelayed(doAutoFocus,1000);
        }
    };    @覆盖
    保护无效onResume(){        super.onResume();
        尝试{
            mCamera = Camera.open();
            如果(mCamera == NULL){
                返回;
            }
        }赶上(例外五){
            e.printStackTrace();
            返回;
        }        米preview.setCamera(mCamera);
        米preview.showSurfaceView();
        米previewing = TRUE;    }    @覆盖
    保护无效的onPause(){
        super.onPause();
        如果(mCamera!= NULL){
            米preview.setCamera(NULL);
            mCamera.cancelAutoFocus();
            mCamera.set previewCallback(NULL);
            mCamera.stop preVIEW();
            mCamera.release();
            米preview.hideSurfaceView();
            米previewing = FALSE;
            mCamera = NULL;
        }
    }    私人无效findSetupViews(){        flCamera preVIEW =(的FrameLayout)findViewById(R.id.flCamera preVIEW);
        ibFlashButton =(的ImageButton)findViewById(R.id.ibFlash);
        ibFlashButton.setOnClickListener(本);        如果(getPackageManager()。hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)){
            ibFlashButton.setVisibility(View.VISIBLE);
            ibFlashButton.setOnClickListener(本);
        }其他{
            ibFlashButton.setVisibility(View.GONE);
        }
    }    @覆盖
    公共无效的onClick(视图v){
        开关(v.getId()){
        案例R.id.ibFlash:
            如果(isFlashOn){
                米preview.setCameraFlashLight(假);
                isFlashOn = FALSE;
                ibFlashButton.setImageResource(R.drawable.flashoff);
            }其他{
                米preview.setCameraFlashLight(真);
                ibFlashButton.setImageResource(R.drawable.flashon);
                isFlashOn = TRUE;
            }
            打破;
        }
    }    @覆盖
    在previewFrame(最后一个字节[]数据,最后的摄像头摄像头){公共无效
        //此处加工QR code,如果相机对焦工作正常
        现在//去掉缩小code张贴问题
    }}

和相机preVIEW类是:

 公共类相机previewNew扩展的ViewGroup实现回调{    公共静态最终诠释CAMERA_BACK = 0;
    公共静态最终诠释CAMERA_FRONT = 1;
    公共相机mCamera = NULL;
    私人上下文的背景下= NULL;    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    尺寸M previewSize;
    清单<尺寸和GT; mSupported previewSizes;
    previewCallback米previewCallback;
    AutoFocusCallback mAutoFocusCallback;    公共摄像头previewNew(上下文的背景下,    previewCallback previewCallback,AutoFocusCallback autoFocusCb){
        超级(上下文);
        米previewCallback = previewCallback;
        mAutoFocusCallback = autoFocusCb;
        this.context =背景;
        mSurfaceView =新SurfaceView(背景);
        addView(mSurfaceView);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(本);        如果(Build.VERSION.SDK_INT< Build.VERSION_ codeS.HONEYCOMB){
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }    }    公共无效setCamera(相机摄像机){
        mCamera =摄像头;
        如果(mCamera!= NULL){
            mSupported previewSizes = mCamera.getParameters()
                    .getSupported previewSizes();
            requestLayout();
        }
    }    @覆盖
    保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){        最终诠释宽度= resolveSize(getSuggestedMinimumWidth()
                widthMeasureSpec);
        最终诠释身高= resolveSize(getSuggestedMinimumHeight()
                heightMeasureSpec);
        setMeasuredDimension(宽度,高度);    }    公共无效hideSurfaceView(){
        mSurfaceView.setVisibility(View.INVISIBLE);
    }    公共无效showSurfaceView(){
        mSurfaceView.setVisibility(View.VISIBLE);
    }    公共无效surfaceCreated(SurfaceHolder持有人){        尝试{
            如果(mCamera!= NULL){
                mCamera.set previewDisplay(支架);
            }
        }赶上(IOException异常除外){
            Log.e(logtag,I​​OException的引起集previewDisplay(),
                    例外);
        }
    }    公共无效surfaceDestroyed(SurfaceHolder持有人){        如果(mCamera!= NULL){
            mCamera.cancelAutoFocus();
            mCamera.stop preVIEW();
        }
    }    公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释W,INT高){
        如果(holder.getSurface()== NULL){            返回;
        }        如果(mCamera!= NULL){            Camera.Parameters参数= mCamera.getParameters();
            米previewSize = getBest previewSize(mCamera.getParameters(),W,H);
            parameters.set previewSize(M previewSize.width,男previewSize.height);
            requestLayout();            mCamera.setParameters(参数);
            mCamera.set previewCallback(M previewCallback);
            mCamera.start preVIEW();
            mCamera.autoFocus(mAutoFocusCallback);
            setCameraDisplayOrientation(0);
        }
    }    私人无效setCameraDisplayOrientation(INT cameraId){
        Camera.CameraInfo信息=新Camera.CameraInfo();
        Camera.getCameraInfo(cameraId,资讯);
        INT旋转=((窗口管理器)的上下文
                .getSystemService(Context.WINDOW_SERVICE))。getDefaultDisplay()
                .getRotation();
        INT度= 0;
        开关(旋转){
        案例Surface.ROTATION_0:
            度= 0;
            打破;
        案例Surface.ROTATION_90:
            度= 90;
            打破;
        案例Surface.ROTATION_180:
            度= 180;
            打破;
        案例Surface.ROTATION_270:
            度= 270;
            打破;
        }        INT结果;
        如果(info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
            结果=(info.orientation +度)360%;
            结果=(360 - 结果)%360; //补偿镜
        }其他{//后置
            结果=(info.orientation - 度+ 360)%360;
        }
        mCamera.setDisplayOrientation(结果);
    }    受保护的静态比较<尺寸和GT; newSizeComparator(){
        返回新的比较<尺寸和GT;(){            @覆盖
            公众诠释比较(尺寸LHS,RHS尺寸){
                返回Integer.valueOf(rhs.height * rhs.width).compareTo(
                        lhs.height * lhs.width);
            }
        };
    }    私人尺寸getBest previewSize(参数参数,诠释屏幕宽度,
            INT screenHeight){
        清单<尺寸和GT; supportedSizes = parameters.getSupported previewSizes();        Collections.sort(supportedSizes,newSizeComparator());        INT previewHeight = screenHeight;
        INT previewWidth =屏幕宽度;        如果(previewHeight> previewWidth){
            INT交换= previewWidth;
            previewWidth = previewHeight;
            previewHeight =掉;
        }        大小bestSize = NULL;
        浮bestRatio = 999;
        对于(规格:supportedSizes){            如果(s.height> s.width){
                INT交换= s.width;
                s.width = s.height;
                s.height =掉;
            }            浮动cameraRatio =((浮点)s.height /(浮点)s.width);
            浮动screenRatio =((浮点)previewHeight)
                    /((浮点)previewWidth);            如果((s.height> = previewHeight)及及(s.width> = previewWidth)){
                浮ratioDiff = cameraRatio - screenRatio;
                如果((ratioDiff&所述; 0.19)及及(ratioDiff> -0.19)
                        &功放;&安培; (Math.abs(bestRatio)GT; Math.abs(ratioDiff))){
                    bestSize =秒;
                    bestRatio = ratioDiff;
                }
            }
        }
        返回bestSize;
    }    公共无效setCameraFlashLight(布尔setFlash){        参数_parameters = mCamera.getParameters();        如果(setFlash){
            _parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
        }其他{
            _parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
        }
        mCamera.setParameters(_parameters);
        mCamera.start preVIEW();
    }    @覆盖
    保护无效onLayout(布尔变化,诠释L,INT T,INT R,INT B){
        如果(变更&放大器;&放大器; getChildCount()大于0){
            最后查看孩子= getChildAt(0);            最终诠释宽度= R - 1;
            最终诠释身高= B - 吨;            INT previewWidth =宽度;
            INT previewHeight =高度;
            如果(M previewSize!= NULL){
                previewWidth = M previewSize.width;
                previewHeight = M previewSize.height;
            }            如果(宽* previewHeight>高* previewWidth){
                最终诠释scaledChildWidth = previewWidth *高
                        / previewHeight;
                child.layout((宽 - scaledChildWidth)/ 2,0,
                        (宽+ scaledChildWidth)/ 2,高度);
            }其他{
                最终诠释scaledChildHeight = previewHeight *宽
                        / previewWidth;
                child.layout(0,(高度 - scaledChildHeight)/ 2,宽度,
                        (高度+ scaledChildHeight)/ 2);
            }
        }    }}


解决方案

我看到一些问题,与你的自动对焦操作code。结果
    结果分析

有周期的自动对焦。

说明


  

A)的相机preVIEW类 mAutoFocusCallback 设置为与 autoFocusCb 相机活动


 公共摄像头previewNew(上下文的背景下,...,AutoFocusCallback autoFocusCb)
    {
        超级(上下文);
        mAutoFocusCallback = autoFocusCb;
        ...
    }


  

B) surfaceChanged 被调用一次,在装载活动的时间。相机被要求自动对焦。


 公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释W,INT高)
    {
        如果(mCamera!= NULL)
        {
            ...
            mCamera.start preVIEW();
            / *自动对焦摄像头,并调用< code基mAutoFocusCallback< / code>自动对焦后。* /
            mCamera.autoFocus(mAutoFocusCallback);
            ...
       }
    }


  

c)在自动对焦的 mAutoFocusCallback 回调被称为完成。 mAutoFocusCallback-> autoFocusCb-> onAutoFocus()结果
      摄像头活动


  Camera.AutoFocusCallback autoFocusCB =新Camera.AutoFocusCallback(){
        公共无效onAutoFocus(布尔成功,相机摄像头){
            mAutoFocusHandler.postDelayed(doAutoFocus,1000);
        }
};


  

D) onAutoFocus 日程安排多一个自动对焦后1000 millisecons,1秒。结果
      摄像头活动


 公共无效onAutoFocus(布尔成功,相机摄像头){
        mAutoFocusHandler.postDelayed(doAutoFocus,1000);
    }


  

e)一名秒钟后消息被传递到处理程序,卡列斯可运行 doAutoFocus ,要求摄像头支持自动对焦,类似b)项


 私人的Runnable doAutoFocus =新的Runnable(){
        公共无效的run(){
            如果(mCamera = NULL&放大器;!&放,M previewing){
                mCamera.autoFocus(autoFocusCB);
            }
        }
    };


  

F)自动对焦完成后, autoFocusCB 再次类似于C)以上调用。和循环下去。


  Camera.AutoFocusCallback autoFocusCB =新Camera.AutoFocusCallback(){
        公共无效onAutoFocus(布尔成功,相机摄像头){
            mAutoFocusHandler.postDelayed(doAutoFocus,1000);
        }
    };

解决方案

我很困惑,为什么这样的实现。周期可能是背后不听闪存启用/禁用电话的原因。您需要删除低于code和空做一些有意义别的离开onAutoFocus()。

  Camera.AutoFocusCallback autoFocusCB =新Camera.AutoFocusCallback(){
    公共无效onAutoFocus(布尔成功,相机摄像头){
    / * REMOVE线以下* /
        mAutoFocusHandler.postDelayed(doAutoFocus,1000);
    }
};

有关自动对焦每当摄像机移到你需要提供手机中的运动传感器的帮助下时间。你可以google一下

希望有所帮助。结果
   快乐编码...

What I have done so far:

I have implemented custom camera for reading qr code which need to continue focus the camera for better qr reading.

My problem is when I use to focus in every one second with the handler the camera flash on\off button dont works or it takes too much time to turning on and off the camera flash light. Every thing works fine when I remove the code of auto focusing the camera every second (The runnable and the handler).

What I want is to focus automatically and quickly whenever camera moves and also able to turn on and off the flash on demand quickly without using Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE because its not available for API<14.

I have used Camera.Parameters.FOCUS_MODE_AUTO but its only focusing the camera once when started thats why i used handler to focus camera every second.

Min SDK Version of project is 9.

My Camera Activity is

public class CameraActivityNew extends Activity implements OnClickListener,
        Camera.PreviewCallback {

    CameraPreviewNew mPreview;
    FrameLayout flCameraPreview;
    ImageButton ibFlashButton;
    Boolean isFlashOn = false;

    Camera mCamera;

    private Handler mAutoFocusHandler;
    private boolean mPreviewing = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        mAutoFocusHandler = new Handler();
        setContentView(R.layout.activity_camera);
        findSetupViews();
        mPreview = new CameraPreviewNew(getApplicationContext(), this,
                autoFocusCB);
        flCameraPreview.addView(mPreview);
    }

    private Runnable doAutoFocus = new Runnable() {
        public void run() {
            if (mCamera != null && mPreviewing) {
                mCamera.autoFocus(autoFocusCB);
            }
        }
    };
    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
        }
    };

    @Override
    protected void onResume() {

        super.onResume();
        try {
            mCamera = Camera.open();
            if (mCamera == null) {
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        mPreview.setCamera(mCamera);
        mPreview.showSurfaceView();
        mPreviewing = true;

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mPreview.setCamera(null);
            mCamera.cancelAutoFocus();
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mPreview.hideSurfaceView();
            mPreviewing = false;
            mCamera = null;
        }
    }

    private void findSetupViews() {

        flCameraPreview = (FrameLayout) findViewById(R.id.flCameraPreview);
        ibFlashButton = (ImageButton) findViewById(R.id.ibFlash);
        ibFlashButton.setOnClickListener(this);

        if (getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA_FLASH)) {
            ibFlashButton.setVisibility(View.VISIBLE);
            ibFlashButton.setOnClickListener(this);
        } else {
            ibFlashButton.setVisibility(View.GONE);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.ibFlash:
            if (isFlashOn) {
                mPreview.setCameraFlashLight(false);
                isFlashOn = false;
                ibFlashButton.setImageResource(R.drawable.flashoff);
            } else {
                mPreview.setCameraFlashLight(true);
                ibFlashButton.setImageResource(R.drawable.flashon);
                isFlashOn = true;
            }
            break;
        }
    }

    @Override
    public void onPreviewFrame(final byte[] data, final Camera camera) {
        // processed here qr code and works fine if camera focus
        //now removed to narrow the code for posting the question
    }

}

And the Camera Preview class is:

public class CameraPreviewNew extends ViewGroup implements Callback {

    public static final int CAMERA_BACK = 0;
    public static final int CAMERA_FRONT = 1;
    public Camera mCamera = null;
    private Context context = null;

    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    Size mPreviewSize;
    List<Size> mSupportedPreviewSizes;
    PreviewCallback mPreviewCallback;
    AutoFocusCallback mAutoFocusCallback;

    public CameraPreviewNew(Context context,

    PreviewCallback previewCallback, AutoFocusCallback autoFocusCb) {
        super(context);
        mPreviewCallback = previewCallback;
        mAutoFocusCallback = autoFocusCb;
        this.context = context;
        mSurfaceView = new SurfaceView(context);
        addView(mSurfaceView);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

    }

    public void setCamera(Camera camera) {
        mCamera = camera;
        if (mCamera != null) {
            mSupportedPreviewSizes = mCamera.getParameters()
                    .getSupportedPreviewSizes();
            requestLayout();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int width = resolveSize(getSuggestedMinimumWidth(),
                widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(),
                heightMeasureSpec);
        setMeasuredDimension(width, height);

    }

    public void hideSurfaceView() {
        mSurfaceView.setVisibility(View.INVISIBLE);
    }

    public void showSurfaceView() {
        mSurfaceView.setVisibility(View.VISIBLE);
    }

    public void surfaceCreated(SurfaceHolder holder) {

        try {
            if (mCamera != null) {
                mCamera.setPreviewDisplay(holder);
            }
        } catch (IOException exception) {
            Log.e("logtag", "IOException caused by setPreviewDisplay()",
                    exception);
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {

        if (mCamera != null) {
            mCamera.cancelAutoFocus();
            mCamera.stopPreview();
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        if (holder.getSurface() == null) {

            return;
        }

        if (mCamera != null) {

            Camera.Parameters parameters = mCamera.getParameters();
            mPreviewSize = getBestPreviewSize(mCamera.getParameters(), w, h);
            parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            requestLayout();

            mCamera.setParameters(parameters);
            mCamera.setPreviewCallback(mPreviewCallback);
            mCamera.startPreview();
            mCamera.autoFocus(mAutoFocusCallback);
            setCameraDisplayOrientation(0);
        }
    }

    private void setCameraDisplayOrientation(int cameraId) {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        int rotation = ((WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        mCamera.setDisplayOrientation(result);
    }

    protected static Comparator<Size> newSizeComparator() {
        return new Comparator<Size>() {

            @Override
            public int compare(Size lhs, Size rhs) {
                return Integer.valueOf(rhs.height * rhs.width).compareTo(
                        lhs.height * lhs.width);
            }
        };
    }

    private Size getBestPreviewSize(Parameters parameters, int screenWidth,
            int screenHeight) {
        List<Size> supportedSizes = parameters.getSupportedPreviewSizes();

        Collections.sort(supportedSizes, newSizeComparator());

        int previewHeight = screenHeight;
        int previewWidth = screenWidth;

        if (previewHeight > previewWidth) {
            int swap = previewWidth;
            previewWidth = previewHeight;
            previewHeight = swap;
        }

        Size bestSize = null;
        float bestRatio = 999;
        for (Size s : supportedSizes) {

            if (s.height > s.width) {
                int swap = s.width;
                s.width = s.height;
                s.height = swap;
            }

            float cameraRatio = ((float) s.height / (float) s.width);
            float screenRatio = ((float) previewHeight)
                    / ((float) previewWidth);

            if ((s.height >= previewHeight) && (s.width >= previewWidth)) {
                float ratioDiff = cameraRatio - screenRatio;
                if ((ratioDiff < 0.19) && (ratioDiff > -0.19)
                        && (Math.abs(bestRatio) > Math.abs(ratioDiff))) {
                    bestSize = s;
                    bestRatio = ratioDiff;
                }
            }
        }
        return bestSize;
    }

    public void setCameraFlashLight(Boolean setFlash) {

        Parameters _parameters = mCamera.getParameters();

        if (setFlash) {
            _parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
        } else {
            _parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
        }
        mCamera.setParameters(_parameters);
        mCamera.startPreview();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed && getChildCount() > 0) {
            final View child = getChildAt(0);

            final int width = r - l;
            final int height = b - t;

            int previewWidth = width;
            int previewHeight = height;
            if (mPreviewSize != null) {
                previewWidth = mPreviewSize.width;
                previewHeight = mPreviewSize.height;
            }

            if (width * previewHeight > height * previewWidth) {
                final int scaledChildWidth = previewWidth * height
                        / previewHeight;
                child.layout((width - scaledChildWidth) / 2, 0,
                        (width + scaledChildWidth) / 2, height);
            } else {
                final int scaledChildHeight = previewHeight * width
                        / previewWidth;
                child.layout(0, (height - scaledChildHeight) / 2, width,
                        (height + scaledChildHeight) / 2);
            }
        }

    }

}

解决方案

I see some issue with your AutoFocus handling code.
Analysis Result

There is cycle in your autofocus.

Explanation

a) Camera Preview Class mAutoFocusCallback is set with the autoFocusCb of the Camera Activity.

    public CameraPreviewNew(Context context,...,AutoFocusCallback autoFocusCb) 
    {
        super(context);
        mAutoFocusCallback = autoFocusCb;
        ...
    }

b)surfaceChanged is called once, at the time of loading the activity. The camera is requested to Auto Focus.

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
    {
        if (mCamera != null) 
        {
            ...
            mCamera.startPreview();
            /*Auto focus camera and call <code>mAutoFocusCallback</code> after autofocus.*/
            mCamera.autoFocus(mAutoFocusCallback); 
            ...
       }
    }

c) On completion of the autofocus the mAutoFocusCallback callback is called. mAutoFocusCallback->autoFocusCb->onAutoFocus()
Camera Activity

    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback()         {
        public void onAutoFocus(boolean success, Camera camera) {
            mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
        }
};

d)onAutoFocus schedules one more autoFocus after 1000 millisecons, 1 sec.
Camera Activity

    public void onAutoFocus(boolean success, Camera camera) {
        mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
    }  

e)After one second the messages is passed to handler that calles the runnable doAutoFocus requesting camera to auto focus, similar to b) above.

    private Runnable doAutoFocus = new Runnable() {
        public void run() {
            if (mCamera != null && mPreviewing) {
                mCamera.autoFocus(autoFocusCB);
            }
        }
    };

f) After completion of the autoFocus, the autoFocusCB is called again, similar to c) above. and cycle continues.

    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
        }
    };

Solution

I am confused why such implementation. The cycle may be reason behind not listening to the flash enable/disable calls. You need to remove the code below and do something meaningful else leave the onAutoFocus() empty.

Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
    public void onAutoFocus(boolean success, Camera camera) {
    /*REMOVE LINE BELOW*/
        mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
    }
};

For auto focusing every time the camera moves you need to take help of the motion sensors provided with the phone. You can google it

Hope that helps.
Happy Coding...

这篇关于为什么连续自动对焦摄像头,处理器不要允许切换相机的闪光灯?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆