切换相机时,Android相机预览冻结吗?

时间:2019-01-31 04:53:49

标签: java android android-camera android-camera2

当我切换相机时,此错误显示“ java.lang.RuntimeException:被调用后正在使用相机”。我释放相机的方法不正确吗?有人可以建议我实现此目的的最佳方法吗?

这是我的CameraActivity.java:

Camera.release()

并这是我CameraPreviewActivity.java

private Camera mCamera;
private CameraPreviewActivity mPreview;
private int cameraId = 0;

private static final int MY_PERMISSIONS_REQUEST_CAMERA = 1;


/**
 * Check if this device has a camera
 */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

/**
 * A safe way to get an instance of the Camera object.
 */

// attempt to get a Camera instance
public static Camera getCameraInstance() {
    Camera c = null;

    try {
        c = Camera.open();
    } catch (Exception e) {
        System.out.println("Camera not working.");
    }
    return c; // returns null if camera is unavailable
}



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camerapreview_activity);

    // Create our Preview view and set it as the content of our activity.
    // Create an instance of Camera

    switchCamera();
    showCamera();
}

public void switchCamera() {
    ToggleButton facingSwitch = (ToggleButton) findViewById(R.id.facingSwitch);
        facingSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
            onDestroy();
            preview.removeAllViews();
            if (isChecked) {
                // The toggle is enabled
                preview.addView(mPreview);
                Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
            } else {
                // The toggle is disabled
                preview.addView(mPreview);
                Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            }

        }
    });
}

protected void onDestroy () {
super.onDestroy();
    if (mCamera != null){
        mCamera.stopPreview();
        mCamera.release();        // release the camera for other applications
        mCamera = null;
    }
}

public void showCamera() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

            // Permission is not granted
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.CAMERA)) {
                Toast.makeText(this, "Camera permission is needed to show the camera preview", Toast.LENGTH_SHORT).show();

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
            } else {

                // No explanation needed; request the permission
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CAMERA},
                        MY_PERMISSIONS_REQUEST_CAMERA);

                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }
        else {
        // Permission has already been granted
        mCamera = getCameraInstance();
        mPreview = new CameraPreviewActivity(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

// Here, thisActivity is the current activity
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_CAMERA: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Create our Preview view and set it as the content of our activity.

                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                showCamera();

            } else {
                Toast.makeText(this, "Permission was not granted", Toast.LENGTH_SHORT).show();
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
    }
}
        // other 'case' lines to check for other
        // permissions this app might request.

1 个答案:

答案 0 :(得分:0)

Camera.open(1)和Camera.open(0)返回一个相机实例,用它代替 mCamera 。这没有解释RuntimeException。

发生此异常是因为您的CameraPreviewActivity保留了对在CameraActivity中打开的Camera实例的单独引用。

最佳做法是仅将引用保留在CameraPreviewActivity类中,然后从CameraActivity类中删除mCamera字段。