Home » Android » android – recreating camera object after error 100 (camera server died)

android – recreating camera object after error 100 (camera server died)

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have classic android app with camera preview (common implem that can be found in many tutorials [marakana etc.]) that is supposed to take picture in a given time interval. Threading and killing threads is done, errors such "method called after release" are handled. But sometimes the well-known error 100 occurs. I accepted the fact that it happens and tried to handle it too. I implemented ErrorCallback and its onError method where the current camera object is released and instantiated a new one as written in official documentation.

But (with no surprise) it is not enough. New camera is maybe wrongly allocated because an message "CameraDemo has been exited unexpectedly" appears now.
I’ve read many docs and examples in hope, that a proper proceeding will be somewhere explained but no one has such problem apparently. So I would like to ask what else should I do beside releasing and creating new camera? Here is the code:

ErrorCallback CEC = new ErrorCallback()
{
    public void onError(int error, Camera camera)
    {
        Log.d("CameraDemo", "camera error detected");
        if(error == Camera.CAMERA_ERROR_SERVER_DIED)
        {
            Log.d("CameraDemo", "attempting to reinstantiate new camera");
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.release(); //written in documentation...
            camera = null;              
            camera = Camera.open();

        }
    }
};

Shortly – if I release and recreate camera in onError callback then RuntimeException Method called after release (takePicture) is raised. So should I somehow assign the surface holder to camera again or recreate the surface holder too?

It would be enough to direct me e.g. to some forums, where it is described or solved, etc. Thanks for any help.

How to&Answers:

In my app to handle the camere i use this :

    public void onResume() {
    super.onResume();
if(mCamera == null)
    mCamera = getCameraInstance():
}


public static Camera getCameraInstance() {
 mCamera = null;
    try {
        mCamera = Camera.open();
Parameters parameters = mCamera.getParameters();
    mCamera.cancelAutoFocus();
    mCamera.setPreviewCallback(yourPreviewCb);
    mCamera.startPreview();
    mCamera.setParameters(parameters);

    mCamera.autoFocus(yourAutoFocusCB);
    } catch (Exception e) {
        //TODO
    }
    return mCamera;
}

The mCamera = null in the getCameraInstance() is just to be sure there is no camera running at all.

I think you need to recreate a complete camera, not just open it with the

camera.open();

Set this in the onResume or in the error callback, depending on your needs.

Answer:

This is how I fixed it, here is a sample of code, think you get the idea:

private Camera camera;

// code...

public Camera getCameraInstance() {
    Camera camera = Camera.open();
    // code...
    camera.setErrorCallback(new ErrorCallback() {
        @Override
        public void onError(int error, Camera camera) {
            if(error == Camera.CAMERA_ERROR_SERVER_DIED) {
                releaseCamera();
                startCamera();
            }
        }
    });
    return camera;
}

protected void startCamera() {
    if(getCamera() == null)
        setCamera(getCameraInstance());
    refreshCamera();
}

protected void releaseCamera() {
    if (getCamera() != null) {
        getCamera().release();
        setCamera(null);
    }
}

public Camera getCamera() {
    return camera;
}

public void setCamera(Camera camera) {
    this.camera = camera;
}