2009-07-02 2 views
2

Я создал класс CapturePreview и класс CameraManager следующим образом:Android: Как перезапустить предварительный просмотр видео после поверхностиDestroyed()?

CapturePreview:

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

}

CameraManager:

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

}

видео просмотр работает так, пока Суб-активность начинается с основного вида деятельности. Когда начинается суб-активность, вызывается CaptureView.surfaceDestroyed(SurfaceHolder holder) и прекращается просмотр видео. Затем, когда суб-активность закрывается, выполняется CaptureView.surfaceCreated(SurfaceHolder holder), но предварительный просмотр видео не запускается.

Кто-нибудь знает, как устранить проблему, чтобы успешно перезапустить предварительный просмотр видео после того, как выполнено поверхностное разрушение (держатель SurfaceHolder)?

Спасибо!

ответ

2

Вы должны освободить камеру при просмотре «surfaceDestroyed», поскольку вы пытаетесь получить доступ к ней снова в «surfaceCreated», что вызовет исключение, если камера уже приобретена.

Смежные вопросы