Android:在surfaceDestroyed()之后如何重新启动视频预览?

Android:在surfaceDestroyed()之后如何重新启动视频预览?,android,video,camera,Android,Video,Camera,我通过以下方式创建了CapturePreview类和CameraManager类: 捕获预览: public class CaptureView extends SurfaceView implements Callback{ private final SurfaceHolder surfaceHolder; FileReaderWriter fileRW; int frameCount; private static final int MSG_FRAME_REFRESHED = 1;

我通过以下方式创建了CapturePreview类和CameraManager类:

捕获预览:

public class CaptureView extends SurfaceView implements Callback{

private final SurfaceHolder surfaceHolder;
FileReaderWriter fileRW;
int frameCount;

private static final int MSG_FRAME_REFRESHED = 1;
private static final int MSG_AUTOFOCUS = 2;

private final CameraManager mCameraManager;

private boolean mRecording;

public CaptureView(Context context, AttributeSet attrs)
{
    super(context, attrs);

    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    CameraManager.init(context);
    mCameraManager = CameraManager.get();

    init(context);
}

public CaptureView(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);

    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    surfaceHolder.setSizeFromLayout();

    CameraManager.init(context);
    mCameraManager = CameraManager.get();

    init(context);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {

    mCameraManager.startPreview();

    //mCameraManager.requestPreviewFrame(mCameraHandler, MSG_FRAME_REFRESHED);
    mCameraManager.requestAutoFocus(mCameraHandler, MSG_AUTOFOCUS);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try
    {
        mCameraManager.openDriver(surfaceHolder);
    }
    catch(Exception e)
    {
        //TODO: display error
    }

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    mCameraManager.stopPreview();
}

private void init(Context context)
{
    setFocusable(true);
    mRecording = false;
    fileRW = new FileReaderWriter();
    frameCount = 0;
}



public void setRecording(boolean isRecording) {
    this.mRecording = isRecording;
}

public boolean isRecording() {
    return mRecording;
}

private Handler mCameraHandler = new CameraHandler();

private class CameraHandler extends Handler
{
    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
        case MSG_FRAME_REFRESHED:
//              String path = "JPGFrame" + frameCount;
//              fileRW.setPath(path);
//              fileRW.WriteToFile((byte[]) msg.obj);
//              frameCount++;

            break;
        }
    }
}
}

摄影机管理器:

public final class CameraManager {

@Override
protected void finalize() throws Throwable {
    closeDriver();
    super.finalize();
}

private static final String TAG = "CameraManager";

private static CameraManager mCameraManager;
private Camera mCamera;
private final Context mContext;
private Point mScreenResolution;
private Rect mFramingRect;
private Handler mPreviewHandler;
private int mPreviewMessage;
private Handler mAutoFocusHandler;
private int mAutoFocusMessage;
private boolean mPreviewing;

public static synchronized void init(Context context) {
    if (mCameraManager == null) {
      mCameraManager = new CameraManager(context);
      mCameraManager.getScreenResolution();
    }
  }

  public static CameraManager get() {
    return mCameraManager;
  }

  private CameraManager(Context context) {
    mContext = context;
    mCamera = null;
    mPreviewing = false;
  }

  public void openDriver(SurfaceHolder holder) throws IOException {
    // "throws IOException added to accommodate Android 1.5
    if (mCamera == null) {
      mCamera = Camera.open();
      setCameraParameters();
      mCamera.setPreviewDisplay(holder);
    }
  }

  public void closeDriver() {
    if (mCamera != null) {
      mCamera.release();
      mCamera = null;
    }
  }

  public void startPreview() {
    if (mCamera != null && !mPreviewing) {
      mCamera.startPreview();
      mPreviewing = true;
    }
  }

  public void stopPreview() {
    if (mCamera != null && mPreviewing) {
      mCamera.setPreviewCallback(null);
      mCamera.stopPreview();
      mPreviewHandler = null;
      mAutoFocusHandler = null;
      mPreviewing = false;
    }
  }


  public void requestPreviewFrame(Handler handler, int message) {
    if (mCamera != null && mPreviewing) {
      mPreviewHandler = handler;
      mPreviewMessage = message;
      mCamera.setPreviewCallback(previewCallback);
    }
  }

  public void requestAutoFocus(Handler handler, int message) {
    if (mCamera != null && mPreviewing) {
      mAutoFocusHandler = handler;
      mAutoFocusMessage = message;
      mCamera.autoFocus(autoFocusCallback);
    }
  }


  public Rect getFramingRect() {
    if (mFramingRect == null) {
      int size = ((mScreenResolution.x < mScreenResolution.y) ? mScreenResolution.x :
          mScreenResolution.y) * 3 / 4;
      int leftOffset = (mScreenResolution.x - size) / 2;
      int topOffset = (mScreenResolution.y - size) / 2;
      mFramingRect = new Rect(leftOffset, topOffset, leftOffset + size, topOffset + size);
    }
    return mFramingRect;
  }


  PreviewCallback previewCallback = new PreviewCallback()
  {

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        if(mPreviewHandler != null)
        {
            Message message = mPreviewHandler.obtainMessage(mPreviewMessage,
                mScreenResolution.x, mScreenResolution.y, data);
                message.sendToTarget();
        }
    } 
  };

  AutoFocusCallback autoFocusCallback = new AutoFocusCallback()
  {

    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        if(mAutoFocusHandler != null)
        {
            Message message = mAutoFocusHandler.obtainMessage(mAutoFocusMessage, success);
            message.sendToTarget();
        }   
    }  
  };

  private void setCameraParameters() {
    Camera.Parameters parameters = mCamera.getParameters();
    parameters.setPreviewSize(mScreenResolution.x, mScreenResolution.y);
    parameters.setPictureFormat(PixelFormat.JPEG);
    parameters.setPreviewFormat(PixelFormat.JPEG);
    mCamera.setParameters(parameters);
  }

  private Point getScreenResolution() {
    if (mScreenResolution == null) {
      WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
      Display display = wm.getDefaultDisplay();
      mScreenResolution = new Point(display.getWidth(), display.getHeight());
    }
    return mScreenResolution;
  }
公共最终类CameraManager{
@凌驾
受保护的void finalize()抛出可丢弃的{
closeDriver();
super.finalize();
}
私有静态最终字符串TAG=“CameraManager”;
专用静态摄影机管理器mCameraManager;
私人摄像机麦卡梅拉;
私有最终上下文mContext;
私有点解析;
私有Rect-mFramingRect;
私人处理程序mPreviewHandler;
私人int mPreviewMessage;
私人经办人莫托福辛德勒;
Mautofocuments私人信息;
私人审查;
公共静态同步void init(上下文){
if(mCameraManager==null){
mCameraManager=新的CameraManager(上下文);
mCameraManager.getScreenResolution();
}
}
公共静态CameraManager get(){
返回mCameraManager;
}
专用CameraManager(上下文){
mContext=上下文;
mCamera=null;
mpr=false;
}
public void openDriver(SurfaceHolder持有者)引发IOException{
//“为适应Android 1.5而添加的异常
if(mCamera==null){
mCamera=Camera.open();
setCameraParameters();
mCamera.setPreviewDisplay(支架);
}
}
公共驱动程序(){
if(mCamera!=null){
mCamera.release();
mCamera=null;
}
}
public void startPreview(){
if(mCamera!=null&&!mpr){
mCamera.startPreview();
mpr=true;
}
}
公众谘询(){
if(mCamera!=null&&mpr){
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewHandler=null;
mAutoFocusHandler=null;
mpr=false;
}
}
public void requestPreviewFrame(处理程序,int消息){
if(mCamera!=null&&mpr){
mPreviewHandler=处理程序;
mPreviewMessage=消息;
mCamera.setPreviewCallback(previewCallback);
}
}
public void requestAutoFocus(处理程序,int消息){
if(mCamera!=null&&mpr){
mAutoFocusHandler=handler;
mAutoFocusMessage=消息;
mCamera.自动对焦(自动对焦返回);
}
}
公共Rect getFramingRect(){
if(mFramingRect==null){
int size=((mScreenResolution.x
}

视频预览会以这种方式正常工作,直到子活动在主活动中启动。当子活动启动时,会调用
CaptureView.surfaceedstroyed(SurfaceHolder holder)
,视频预览会停止。然后当子活动关闭
CaptureView.surfaceCreated(SurfaceHolder holder holder)
已执行,但视频预览未启动

是否有人知道如何解决问题,以便在执行surfaceDestroyed(SurfaceHolder holder holder)后成功重新启动视频预览


谢谢!

您必须在“SurfacedStroyed”处释放相机,因为您正试图在“SurfacecCreated”中再次获取对它的访问权限,如果已经获取相机,则会引发异常