SurfaceView Camera.getCameraParameters返回空引用

时间:2018-07-03 17:38:40

标签: android surfaceview

我正在使用表面视图构建相机应用程序,经过几次测试后运行正常,随后的测试发现该应用程序在logcat中崩溃并出现此异常:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()' on a null object reference
    at com.jjoey.envisionocr.MainActivity.setCameraFocus(MainActivity.java:102)
    at com.jjoey.envisionocr.MainActivity.startCamera(MainActivity.java:54)
    at com.jjoey.envisionocr.MainActivity.checkPerms(MainActivity.java:69)
    at com.jjoey.envisionocr.MainActivity.onCreate(MainActivity.java:37)
    at android.app.Activity.performCreate(Activity.java:6671)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)

这发生在代码中的以下行号上:Camera.Parameters parameters = camera.getParameters();我打电话给了Camera.open(id) with the id set to back camera

这是我的活动代码:

public class MainActivity extends AppCompatActivity {

private FrameLayout frameLayout; //camera surface container
private ImageView captureImgBtn;

private Camera camera;
private CameraPreview preview;
private int type = 0;

public static final int REQ_CAMERA = 102;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    checkPerms();

    initViews();

   //        startCamera();

    captureImgBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            camera.takePicture(mShutterCallback, null, mPictureCallback);
        }
    });

}

private void startCamera() {
    if (checkCameraHardware()){
        setCameraFocus();
        camera = getCameraInstance(type);
        preview = new CameraPreview(this, camera, type);
        frameLayout.addView(preview);


    } else {
        Toast.makeText(getApplicationContext(), "Device not support camera feature", Toast.LENGTH_SHORT).show();
    }
}

private void checkPerms() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
        askPerms();
    } else {
        startCamera();
    }
}

private void askPerms() {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQ_CAMERA);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case REQ_CAMERA:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                startCamera();
            } else {
                finish();
            }
            break;
    }
}

private void releaseCameraAndPreview() {
    if (camera != null) {
        camera.release();
        camera = null;
    }
}

private void setCameraFocus() {

    releaseCameraAndPreview();

    Camera.Parameters parameters = camera.getParameters();
    if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
    } else {
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    }
    camera.setParameters(parameters);
}

private Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
    @Override
    public void onShutter() {
        // do ntn
    }
};

private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] bytes, Camera camera) {

    }
};

private Camera getCameraInstance(int type) {
    Camera cam = null;
    try {
        cam = Camera.open(type);
    } catch (Exception e){
        Log.d("tag", "Error setting camera not open " + e);
        e.printStackTrace();
    }
    return cam;
}

private boolean checkCameraHardware() {
    if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        return true;
    } else {
        return false;
    }
}

private void initViews() {
    frameLayout = (FrameLayout) findViewById(R.id.frameCamera);
    captureImgBtn = findViewById(R.id.captureImgBtn);
}

}

我已经这样创建了CameraPreview类:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private Context context;
private SurfaceHolder holder;
private Camera camera;
private int cameraType;

public CameraPreview(Context context, Camera camera, int cameraType) {
    super(context);
    this.context = context;
    this.camera = camera;
    this.cameraType = cameraType;
    holder = getHolder();
    holder.addCallback(this);
}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
    try {
        camera.setPreviewDisplay(surfaceHolder);
        setCameraDisplayOrientation((Activity) context, cameraType, camera);
        camera.startPreview();
    } catch (IOException e) {
        Log.d("tag", "Error setting camera preview: " + e.getMessage());
        e.printStackTrace();
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    if (holder == null)
        return;
    try {
        camera.stopPreview();
        camera.setPreviewDisplay(surfaceHolder);
        setCameraDisplayOrientation((Activity) context, cameraType, camera);
        camera.startPreview();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void setCameraDisplayOrientation(Activity activity,
                                               int cameraId, android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info =
            new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().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;
    }
    camera.setDisplayOrientation(result);
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    camera.release();
}

}

有人知道为什么会出现此错误以及如何解决吗?我尝试过使用这种方法在打开相机之前将其释放,如下所示:

private void releaseCameraAndPreview() {
    if (camera != null) {
        camera.release();
        camera = null;
    }
}

,但这似乎不是解决方案。任何帮助,将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

releaseCameraAndPreview()的调用将camera对象设置为null。因此,当您调用camera.getParameters()时,您尝试在null上调用方法。