Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为什么带处理器的连续自动对焦相机不允许切换闪光灯?_Android_Android Camera - Fatal编程技术网

Android 为什么带处理器的连续自动对焦相机不允许切换闪光灯?

Android 为什么带处理器的连续自动对焦相机不允许切换闪光灯?,android,android-camera,Android,Android Camera,到目前为止我所做的: 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; Su

到目前为止我所做的:

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

    }

}
我已经实现了用于读取二维码的定制摄像头,需要继续聚焦摄像头以更好地读取二维码

我的问题是当我使用处理器每秒钟对焦一次时,相机闪光灯的“开/关”按钮不起作用,或者打开和关闭相机闪光灯需要太多时间。当我删除每秒自动对焦相机的代码(runnable和handler)时,一切都很好

我想要的是在相机移动时自动快速对焦,并且能够根据需要快速打开和关闭闪光灯,而无需使用
camera.Parameters.focus\u MODE\u CONTINUOUS\u PICTURE
,因为它不适用于
API previewWidth){
int swap=previewWidth;
previewWidth=PreviewWight;
预览视图=交换;
}
大小bestSize=null;
浮动比率=999;
用于(尺寸s:支持的尺寸){
如果(s.高度>s.宽度){
int swap=s.width;
s、 宽度=s.高度;
s、 高度=交换;
}
浮动摄像机=((浮动)s.高度/(浮动)s.宽度);
浮动屏幕比率=((浮动)预览视图)
/((浮动)预览宽度);
如果((s.height>=预览宽度)和&(s.width>=预览宽度)){
浮动比率IdIff=摄像机-屏幕比率;
如果((ratioDiff<0.19)和&(ratioDiff>-0.19)
&&(数学绝对值(最佳比率)>数学绝对值(比率系数))){
最佳尺寸=s;
最佳比率=ratioDiff;
}
}
}
返回最佳大小;
}
公共无效设置照相机手电筒(布尔设置闪光灯){
参数_Parameters=mCamera.getParameters();
如果(设置闪存){
_参数设置闪光模式(参数闪光模式);
}否则{
_parameters.setFlashMode(parameters.FLASH_MODE_OFF);
}
mCamera.setParameters(_参数);
mCamera.startPreview();
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
如果(已更改&&getChildCount()>0){
最终视图子对象=getChildAt(0);
最终整数宽度=r-l;
最终内部高度=b-t;
int previewWidth=宽度;
亮度=高度;
if(mPreviewSize!=null){
previewWidth=mPreviewSize.width;
PreviewView=mPreviewSize.height;
}
如果(宽度*预览宽度>高度*预览宽度){
最终整数scaledChildWidth=预览宽度*高度
/预演;
布局((宽度-scaledChildWidth)/2,0,
(宽度+缩放儿童宽度)/2,高度);
}否则{
最终int scaledChildHeight=预览视图*宽度
/预览宽度;
布局(0,(高度-缩放儿童高度)/2,宽度,
(身高+缩放儿童身高)/2);
}
}
}
}

您的应用程序似乎不需要使用
AutoFocusCallBack
,因为您所做的只是
延迟1秒

要始终对焦,您可以使用
focus\u MODE\u CONTINUOUS\u PICTURE
(阅读更多内容)这样(
setFocus
方法在
CameraPreview
中,而不是在
Activity
中):

并在
SurfaceChanged
中调用它:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

    // You need to choose the most appropriate previewSize for your app
    Camera.Size previewSize = previewSizes.get(0);

    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setRotation(90);
    mCamera.setParameters(parameters);
    mCamera.startPreview();

    setFlash(true);
    setZoomLevel(5);
    setFocus();

    Log.w(TAG, "surfaceChanged()");
}

希望它能帮助你!如果您对我的答案有任何疑问,请随时发表评论。

我发现您的自动对焦处理代码存在一些问题。
分析结果

自动对焦中有一个循环

解释

a) 相机预览类
mautofocuscalback
通过相机活动的
autoFocusCb
进行设置

b) surfaceChanged在加载活动时调用一次。要求相机自动对焦

c) 自动对焦完成后,调用
mautofocuscalback
回调<代码>MautoFocuscalBack->autoFocusCb->onAutoFocus()

摄像机活动

d)
自动对焦
计划在1000毫秒1秒后再进行一次自动对焦。
摄像机活动

e) 一秒钟后,消息被传递给调用runnable
doAutoFocus
请求相机自动对焦的处理程序,类似于上面的b)

f) 自动对焦完成后,再次调用
autoFocusCB
类似于上面的c)。循环继续。

解决方案

我不明白为什么要这样执行。该周期可能是不监听闪存启用/禁用呼叫的原因。您需要删除下面的代码,并执行一些有意义的操作,使onAutoFocus()保持为空

要在相机每次移动时自动对焦,您需要借助手机附带的运动传感器。你可以用谷歌搜索

希望有帮助。

快乐编码

虽然此操作必须延迟,但如果要切换相机参数,最好按以下顺序操作

mCamera.stopPreview();
mCamera.setParameters(params); // set flash on in Camera parameters
mCamera.startPreview();

我不想在自动对焦回调中做任何其他事情,因为预览回调将继续查找二维码,我已经尝试过了,并且可以正常工作。我的问题是它不允许我正确地切换闪光灯。另一件事是,连续聚焦模式仅在api>=14中可用,因此您的目标设备的api低于14,我不知道这一点。我在API 15的应用程序中使用了这个。聚焦模式连续图片可以解决你的问题
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();

    // You need to choose the most appropriate previewSize for your app
    Camera.Size previewSize = previewSizes.get(0);

    parameters.setPreviewSize(previewSize.width, previewSize.height);
    parameters.setRotation(90);
    mCamera.setParameters(parameters);
    mCamera.startPreview();

    setFlash(true);
    setZoomLevel(5);
    setFocus();

    Log.w(TAG, "surfaceChanged()");
}
public void setFlash(boolean isFlashOn) {
    Camera.Parameters p = mCamera.getParameters();
    if (isFlashOn) {
        p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        mCamera.setParameters(p);
        mCamera.startPreview();
    } else {
        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        mCamera.setParameters(p);
        mCamera.startPreview();
    }
    Log.w(TAG, "setFlash()");
}
    public CameraPreviewNew(Context context,...,AutoFocusCallback autoFocusCb) 
    {
        super(context);
        mAutoFocusCallback = autoFocusCb;
        ...
    }
    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); 
            ...
       }
    }
    Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback()         {
        public void onAutoFocus(boolean success, Camera camera) {
            mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
        }
};
    public void onAutoFocus(boolean success, Camera camera) {
        mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
    }  
    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);
        }
    };
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
    public void onAutoFocus(boolean success, Camera camera) {
    /*REMOVE LINE BELOW*/
        mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
    }
};
mCamera.stopPreview();
mCamera.setParameters(params); // set flash on in Camera parameters
mCamera.startPreview();