Android camera: the application has passed the NULL surface

I found some questions about this, but there are no answers, so I hope someone can have some understanding. When I try to swap the camera, I call the swapCamera function below. However, the camera preview simply freezes (the application did not freeze, although only viewing the camera in real time).

When I open the application for the first time, everything works fine. However, I noticed something interesting. When I exit the memory address of the _surfaceHolder object (i.e., my SurfaceHolder object), it gives me one value, but whenever I request this value after the application finishes running and that's it, this memory address has changed.

Also, the error he gives me when I swapCamera is very confused. I left _surfaceHolder before passing it to the camera in _camera.setPreviewDisplay(_surfaceHolder); and it is not null before it passes.

Any help is greatly appreciated.

I noticed an interesting behavior

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
    private SurfaceHolder _surfaceHolder;
    private Camera _camera;
    boolean _isBackFacing;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        _camera = camera;
        _isBackFacing = true;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        _surfaceHolder = getHolder();
        _surfaceHolder.addCallback(this);
    }

    void refreshCamera()
    {
        try {
            _camera.setPreviewDisplay(_surfaceHolder);
            _camera.startPreview();
        } catch (IOException e) {
            Log.d("iCamera", "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceCreated(SurfaceHolder holder)
    {
//        The Surface has been created, now tell the camera where to draw the preview.
        refreshCamera();
    }

    public void surfaceDestroyed(SurfaceHolder holder)
    {
        // empty. Take care of releasing the Camera preview in your activity.
        _surfaceHolder.removeCallback(this);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
    {
         // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (_surfaceHolder.getSurface() == null){
            // preview surface does not exist
            return;
        }

        try {
            _camera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes her
        _camera.setDisplayOrientation(90);

        // _startPoint preview with new settings
        refreshCamera();
    }

    public void swapCamera()
    {
        Camera cam = null;
        int cameraCount = Camera.getNumberOfCameras();
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        _camera.stopPreview();
        _camera.release();
        for (int i = 0; i < cameraCount; i++)
        {
            Camera.getCameraInfo(i,cameraInfo);
            if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && _isBackFacing == true)
            {
                try
                {
                    _camera = Camera.open(i);

                }catch (RuntimeException e)
                {
                    Log.e("Error","Camera failed to open: " + e.getLocalizedMessage());
                }
            }

            if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK && _isBackFacing == false)
            {
                try
                {
                    _camera = Camera.open(i);
                }catch (RuntimeException e)
                {
                    Log.e("Error","Camera failed to open: " + e.getLocalizedMessage());
                }
            }
        }

        _isBackFacing = !_isBackFacing;
        refreshCamera();
    }
}
+4
source share
1 answer

So, after a lot of debugging and digging, I found that the onResume function was the culprit.

In it, I “updated” the camera variable if it got lost between switching contexts.

public void onResume()
{
    super.onResume();
    _cameraPreview = new CameraPreview(getActivity());
}

, . , , , SurfaceHolder, Android ( ) SurfaceHolder. "" (.. ) onResume, .

, , , , , null surfaceHolder, (, OLD null ). , , , Holder .

+1

Source: https://habr.com/ru/post/1588879/


All Articles