Question

J'ai créé une classe CapturePreview et classe CameraManager de la manière suivante:

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

}

L'aperçu vidéo fonctionne bien ainsi jusqu'à ce que la sous-activité commence dans l'activité principale. Lorsque la sous-activité commence l'est appelée et CaptureView.surfaceDestroyed(SurfaceHolder holder) l'arrêt aperçu vidéo. Ensuite, lorsque la sous-activité ferme l'est exécutée CaptureView.surfaceCreated(SurfaceHolder holder), mais l'aperçu vidéo ne démarre pas.

Quelqu'un sait comment résoudre le problème afin de relancer avec succès aperçu vidéo après surfaceDestroyed (titulaire de SurfaceHolder) est exécutée?

Merci!

Était-ce utile?

La solution

Vous devez libérer la caméra à « surfaceDestroyed » car vous essayez d'obtenir un accès à nouveau dans « surfaceCreated », qui vous lancera une exception si l'appareil est déjà acquis.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top