Search code examples
javaandroidannotationsfindbugsunboxing

Unboxing of cameraCharacteristics may produce Nullpointer Exception and FindBugs


I can't manage to handle the following warning which causes FindBugs to throw an error.

Error

I am using the camera2 api. As you can see I am already checking for null and additionally catching a possible NullPointer exception. The .get method of the CameraCharacteristics class is annotated with Nullable so this error comes up. I have no clue how I can prevent this. Checks for null seem not to do the job.

Meanwhile I added the SuppressFBWarnings Annotation to my project. But even when I suppress the warning like this:

@SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH")
private void setUpCamera(int width, int height) {
    try {
        for (String cameraId : cameraManager.getCameraIdList()) {
            CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);

            if (cameraCharacteristics != null && cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) != null) {
                int lensFaceingCameraCharacteristics = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);

                if (cameraFacing == lensFaceingCameraCharacteristics) {
                    StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                    previewSize = getPreviewSize(streamConfigurationMap.getOutputSizes(SurfaceTexture.class), width, height);
                    this.cameraId = cameraId;
                }
            }
        }
    } catch (CameraAccessException | NullPointerException eae) {
        Logger.error(eae.getMessage());
    }
}

the error still comes up in the FindBugs analysis.


Solution

  • This is an autoboxing pitfall. Lets take a look at the line:

    int lensFaceingCameraCharacteristics = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
    

    In case if cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) will return null then autoboxing will produce NPE because null can`t be converted to a primitive int.

    Here is some interesting article.

    You can refactor your variables/fields to be Wrapper classes like Integer, Float, etc.

    private Integer cameraFacing;
    

    But in this case, you probably will need to solve some new NPE warnings. So you can just refactor code like that:

     if (cameraCharacteristics != null && cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) != null) {
                Integer lensFaceingCameraCharacteristics = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
    
                if (lensFaceingCameraCharacteristics != null 
                     && cameraFacing == lensFaceingCameraCharacteristics) {
                    StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                    previewSize = getPreviewSize(streamConfigurationMap.getOutputSizes(SurfaceTexture.class), width, height);
                    this.cameraId = cameraId;
                }
            }