SetParameter很少有android设备失败

时间:2015-03-10 14:10:26

标签: android android-camera

我已经构建了一个Android相机应用程序,适用于少数设备,在某些设备中,它会在开始预览之前崩溃。尝试使用所有stackOverflow解决方案,但没有任何方法可以帮助我。

我的预览课程

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    protected List<Camera.Size> mSupportedPreviewSizes;
    private List<Camera.Size> mSupportedPictureSizes;
    private Camera.Size mPreviewSize;
    private Camera.Size mPictureSize;
    private Camera mCamera;

    public CameraPreview(Context context) {
        super(context);
    }

    public CameraPreview(Activity activity, Camera camera) {
        super(activity);
        mCamera = camera;
        setCamera(mCamera);
        mCamera.getParameters().getSupportedPreviewFpsRange();
        SurfaceHolder mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mHolder.setKeepScreenOn(true);

    }

    public void setCamera(Camera camera) {

        mCamera = camera;
         if (mCamera != null) {
            mCamera.setDisplayOrientation(getDisplayOrientation());
            Camera.Parameters parameters = mCamera.getParameters();
            mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
            mSupportedPictureSizes = parameters.getSupportedPictureSizes();
            requestLayout();
            parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
            parameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
            int index = parameters.getExposureCompensation();
            parameters.setExposureCompensation(index);
            mCamera.setParameters(parameters);
        }
    }


    public int getDisplayOrientation() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, info);
        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();

        int rotation = display.getRotation();
        int degree = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degree = 0;
                break;
            case Surface.ROTATION_90:
                degree = 90;
                break;
            case Surface.ROTATION_180:
                degree = 180;
                break;
            case Surface.ROTATION_270:
                degree = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degree) % 360;
            result = (360 - result) % 360;
        } else {
            result = (info.orientation - degree + 360) % 360;
        }
        return result;
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (mCamera != null) {
                mCamera.setPreviewDisplay(holder);
            }

        } catch (IOException e) {
            Log.d("DG_DEBUG", "Error setting camera preview in surfaceCreated: " + e.getMessage());
        }
    }


    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);
        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
        if(mSupportedPictureSizes != null){
            mPictureSize = getOptimalPictureSize();
        }
    }

    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height) {
        Camera.Size optimalSize = null;
        final double ASPECT_TOLERANCE = 0.01;
        double targetRatio = (double) height / width;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = height;

        for (Camera.Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }

//这里返回最佳预览尺寸。 例如:Moto G具有720 * 1280的屏幕分辨率,通过将optimalSize返回为720 * 1280,它可以完美地工作。

但是对于具有相同分辨率720 * 1280的Moto X,它在开始预览之前崩溃了。返回宽度= 640,高度= 480,这是不正确的。

            Log.d("getOptimalPreviewSize",
                    String.format(
                            "getOptimalPreviewSize result: width = %d, height = %d for input width = %d, height = %d",
                            optimalSize.width, optimalSize.height, width,
                            height));
        return optimalSize;
    }

    private Camera.Size getOptimalPictureSize() {
        if (mCamera == null) {
            return null;
        }
        List<Camera.Size> cameraSizes = mCamera.getParameters().getSupportedPictureSizes();
        Camera.Size optimalSize = mCamera.new Size(0, 0);
        double previewRatio = (double) mPreviewSize.width / mPreviewSize.height;
        for (Camera.Size size : cameraSizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - previewRatio) > 0.01f)
                continue;
            if (size.height > optimalSize.height) {
                optimalSize = size;
            }
        }

        if (optimalSize.height == 0) {
            for (Camera.Size size : cameraSizes) {
                if (size.height > optimalSize.height) {
                    optimalSize = size;
                }
            }
        }
        return optimalSize;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (mCamera != null) {

            Camera.Parameters parameters = mCamera.getParameters();
            List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
             Camera.Size mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
            parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
           parameters.setPictureSize(mPictureSize.width, mPictureSize.height);
            mCamera.setParameters(parameters);
            mCamera.startPreview();

        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.release();
            }
        } catch (Exception e) {
            Log.d("SurfaceDestroyed", " Error handling surface destroy method");
        }
    }
}

0 个答案:

没有答案