2009-07-02 15 views
2

Ich habe eine CapturePreview Klasse und CameraManager Klasse die folgende Art und Weise erstellt:Android: Wie startet man die Videovorschau nach dem SurfaceDestroyed()?

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

}

Die Video-Vorschau funktioniert auf diese Weise bis zum Die Unteraktivität beginnt in der Hauptaktivität. Wenn die Unteraktivität beginnt, wird CaptureView.surfaceDestroyed(SurfaceHolder holder) aufgerufen und die Videovorschau wird beendet. Wenn dann die Unteraktivität schließt, wird die CaptureView.surfaceCreated(SurfaceHolder holder) ausgeführt, aber die Videovorschau startet nicht.

Kann jemand das Problem beheben, um die Videovorschau nach der Ausführung von SurfaceDestroyed (SurfaceHolder holder) erfolgreich neu zu starten?

Danke!

Antwort

2

Sie müssen die Kamera bei 'surfaceDestroyed' freigeben, da Sie versuchen, den Zugriff auf 'surfaceCreated' erneut zu aktivieren, was eine Ausnahme auslöst, wenn die Kamera bereits erfasst wurde.

Verwandte Themen