在错误100(相机服务死亡)之后重新创建相机对象

9

我有一个经典的Android应用程序,其中包括相机预览(常见实现可以在许多教程中找到[例如 marakana]),旨在在给定时间间隔内拍摄照片。线程处理和终止线程等操作已完成,例如处理“方法在释放后调用”的错误。但有时会出现众所周知的错误100。我接受了它发生的事实,并尝试着对其进行处理。我实现了ErrorCallback及其onError方法,其中当前相机对象被释放并按照官方文档的指示重新实例化了一个新的相机。

但是(并不奇怪)这还不够。新相机可能分配错误,因为现在会出现消息“CameraDemo意外退出”的情况。我阅读了许多文档和示例,希望能够找到适当的解决方法,但显然没有人遇到过这样的问题。所以我想问除了释放和创建新相机之外,我还应该做些什么?以下是代码:

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();

        }
    }
};

简单来说,如果我在onError回调中释放并重新创建相机,则会引发RuntimeException方法在释放后被调用(takePicture)。所以我应该如何再次将表面持有者分配给相机或重新创建表面持有者呢?

如果您能直接指导我到一些论坛上,其中描述或解决了这个问题,那就足够了。谢谢任何帮助。


你找到解决方案了吗?请分享。 - Gena
2个回答

0

这是我如何解决的,这里有一段代码示例,你应该能明白我的意思:

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;
}

0
在我的应用程序中处理相机时,我使用以下代码:
    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;
}

在getCameraInstance()中,mCamera = null只是为了确保没有任何相机正在运行。

我认为你需要重新创建一个完整的相机,而不仅仅是打开它。

camera.open();

根据您的需求,在onResume或错误回调中设置此项。


警告!当surfaceChanged在表面改变(例如大小)时被调用,如果Camera对象没有重新制作,如果屏幕大小发生变化,将导致错误100。这是由于相机屏幕被修改而导致崩溃(在旧设备上,相机有时会出现滞后并卡住,导致预览屏幕大小发生变化)。换句话说,请务必注意surfaceChanged,它也容易创建错误100。 - basickarl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接