Android Camera2 API switch back - front cameras

19,969

Solution 1

What you need to do is introduce new variables:

public static final String CAMERA_FRONT = "1";
public static final String CAMERA_BACK = "0";

private String cameraId = CAMERA_BACK;

remove cameraId local variable from openCamera method.

public void switchCamera() {
    if (cameraId.equals(CAMERA_FRONT)) {
        cameraId = CAMERA_BACK;
        closeCamera();
        reopenCamera();
        switchCameraButton.setImageResource(R.drawable.ic_camera_front);

    } else if (cameraId.equals(CAMERA_BACK)) {
        cameraId = CAMERA_FRONT;
        closeCamera();
        reopenCamera();
        switchCameraButton.setImageResource(R.drawable.ic_camera_back);
    }
}

public void reopenCamera() {
    if (mTextureView.isAvailable()) {
        openCamera(mTextureView.getWidth(), mTextureView.getHeight());
    } else {
        mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
    }
}

Solution 2

After looking at MrOnyszko answer i followed a slightly different approach:

In the Camera2Basic Tutorial a lens facing direction is used to set up the right camera, so i changed this direction before closing and reopening the camera.

private void switchCamera() {
    if (mCameraLensFacingDirection == CameraCharacteristics.LENS_FACING_BACK) {
        mCameraLensFacingDirection = CameraCharacteristics.LENS_FACING_FRONT;
        closeCamera();
        reopenCamera();

    } else if (mCameraLensFacingDirection == CameraCharacteristics.LENS_FACING_FRONT) {
        mCameraLensFacingDirection = CameraCharacteristics.LENS_FACING_BACK;
        closeCamera();
        reopenCamera();
    }
}

private void reopenCamera() {
    if (mTextureView.isAvailable()) {
        openCamera(mTextureView.getWidth(), mTextureView.getHeight());
    } else {
        mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
    }
}


private void setUpCameraOutputs(int width, int height) {
    Activity activity = getActivity();
    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
    try {
        for (String cameraId : manager.getCameraIdList()) {
            CameraCharacteristics characteristics
                    = manager.getCameraCharacteristics(cameraId);

            Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
            if (facing != null && facing != mCameraLensFacingDirection) {
                continue;
            }
            ...
Share:
19,969
J.M.
Author by

J.M.

Updated on June 03, 2022

Comments

  • J.M.
    J.M. almost 2 years

    I'm creating a custom camera capturing videos with the new camera2 API.

    My code is strongly inspired from the code provided by Google here. My camera preview has a button to switch from back to front camera and then from front to back camera. The "camera preview" activity is launched with the back camera by default.

    For some reason, when I click on the "switch/swap camera" button for the first time, it brings be to the front camera as it should, BUT everytime I click again, the switch/swap doesn't work anymore: the preview (on the front camera) fades a little bit, like if something is happening, but it remains on the currently selected (front) camera.

    Here is my code :

    In a RecordVideoFragment, in the onViewCreated:

    //  Switch camera button
            switchCameraButton = (ImageButton) view.findViewById(R.id.button_switch_camera);
            // Listener for Switch cameras button
            switchCameraButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switchCameras();
                }
            });
    

    And here is the switchCameras() function:

    private void  switchCameras() {
            mCameraOpenCloseLock.release();
            mCameraDevice.close();
    
            CameraManager mCameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
            try {
                String mCameraId = mCameraManager.getCameraIdList()[0];
                if (mCameraId.equals("0")) {   // If currently on FRONT camera (0 = CameraCharacteristics.LENS_FACING_FRONT)
                    mCameraId = "1";           // switch to BACK camera (1 = CameraCharacteristics.LENS_FACING_BACK)
                    switchCameraButton.setImageResource(R.drawable.ic_camera_front);
                } else {  // If currently on BACK camera
                    mCameraId = "0"; // switch to front camera
                    switchCameraButton.setImageResource(R.drawable.ic_camera_back);
                }
                try {
                    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
                            == PackageManager.PERMISSION_GRANTED) {
                        mCameraManager.openCamera(mCameraId, mStateCallback, null);
                    } else {
                        requestVideoPermissions();
                    }
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            } catch (CameraAccessException e) {
                Toast.makeText(getActivity(), "Cannot access the camera.", Toast.LENGTH_SHORT).show();
                getActivity().finish();
            }
        }
    

    If you have any idea on what's happening that would save me. I have been bugging on this for days. Thank you very much

  • Andrey Solera
    Andrey Solera almost 7 years
    when I use this the size of the preview changes... how can I prevent this?
  • MrOnyszko
    MrOnyszko almost 7 years
    Check if your texture view gives the same dimensions because at reopenCamera method this is set again.
  • Rishikesh pathak
    Rishikesh pathak almost 7 years
    I followed your code but its not wotking for me.I saw in documentation for camera2 in "setUpCameraOutputs" method Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) { continue; } So i removed this condition but still its not working.i followed this
  • Debdeep
    Debdeep over 6 years
    CameraDevice throws exception while switching too fast.
  • Frank Eno
    Frank Eno almost 6 years
    best and easiest answer, if you use Camera2Basic sample code
  • Yudi karma
    Yudi karma about 5 years
    nothing change to methodd setUpcameraoutputs ? i see thats ghave logic to continue if facing lens is Front. what makes that show output from front facing camera ??
  • IAmCoder
    IAmCoder about 5 years
    This still needs a variable: private int mCameraLensFacingDirection = CameraCharacteristics.LENS_FACING_FRONT;