Android相机预览错误

时间:2011-11-15 16:19:51

标签: android camera preview

这是我的CameraView类:

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
private Camera camera=null;

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

    SurfaceHolder holder = this.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public boolean isVisible(){
    return this.getVisibility()==View.VISIBLE;
}

public void show(){
    this.setVisibility(View.VISIBLE);
}

public void hide(){
    this.setVisibility(View.GONE);
}

public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    camera.setPreviewCallback(this);

    try {
        camera.setPreviewDisplay(holder);
    }catch (IOException e) {
        Log.e("Preview Exception", e.getMessage());
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {        
    if(camera!=null){
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera=null;
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        
    if(camera==null || !(w>0&&h>0))
        return;

    Camera.Parameters parameters = camera.getParameters();
    parameters.setPreviewSize(w, h);

    camera.setParameters(parameters);
    camera.startPreview();
}

@Override
public void onPreviewFrame(byte[] data, Camera camera) {

}
}

在我的活动中,我有两个按钮 - 其中一个显示相机预览,第二个隐藏它(使用CameraView.show()和CameraView.hide())方法。

除了一个案例外,它几乎可以正常工作: 如果我使用CameraView.hide()隐藏预览,请按HOME按钮(应用程序将分叉到背景)并再次将应用程序带到前面,我无法再开始预览。 当我调用CameraView.show()(按下按钮)时,会出现CameraView,但预览不会启动。

对我来说它看起来像android bug,因为在其他情况下一切正常 - 我正在运行android 2.1。

有人能帮助我吗? 谢谢!

PS。根据mmeyer的帖子(仍然没有工作),这是更新的课程:

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback {
private Camera camera=null;
private SurfaceHolder holder;

public CameraView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void initialize(){
    camera=Camera.open();

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

public void release(){
    holder.removeCallback(this);

    if(camera!=null){
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera=null;
    }
}

public boolean isVisible(){
    return this.getVisibility()==View.VISIBLE;
}

public void show(){
    this.setVisibility(View.VISIBLE);
}

public void hide(){
    this.setVisibility(View.GONE);
}

public void surfaceCreated(SurfaceHolder holder) {      
}

public void surfaceDestroyed(SurfaceHolder holder) {
    if(camera!=null)
        camera.stopPreview();
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        
    if(camera==null || !(w>0&&h>0))
        return;


    try {
        camera.setPreviewDisplay(holder);
    }catch (IOException e) {
        Log.e("Preview Exception", e.getMessage());
    }

    Camera.Parameters parameters = camera.getParameters();
    parameters.setPreviewSize(w, h);

    camera.setParameters(parameters);
    camera.startPreview();
}

@Override
public void onPreviewFrame(byte[] data, Camera camera) {

}
}

2 个答案:

答案 0 :(得分:2)

我怀疑你需要在onDestroy中最低限度地释放相机,理想情况是在onPause中,否则你最终会挂起相机驱动程序。

我用于相机预览的模式是:

onResume:
   - get a ref to camera with Camera.open();
   - sv = (SurfaceView)this.findViewById(R.id.capture_SurfaceView);
                mHolder = sv.getHolder(); 
                mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
                mHolder.setSizeFromLayout();
                mHolder.addCallback(this); 
  surfaceChanged:
    - Camera.setPreviewDisplayHolder()
    - Camera.startPreview()
  onPause:
    - Camera.stopPreview
    - SurfaceHolder.removeCallback()
    - Camera.release()

答案 1 :(得分:0)

我有一个工作版本:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "CameraPreview";

    private SurfaceHolder surfaceHolder;
    private Camera camera;

    public CameraPreview(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed

        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here,
        // make sure to stop the preview before resizing or reformatting it

        if (surfaceHolder.getSurface() == null){
            // Preview surface does not exist
            return;
        }

        // Stop preview before making changes
        try {
            camera.stopPreview();
        } catch (Exception e){
            // ignore: tried to stop a non-existent preview
        }

        // Set preview size and make any resize, rotate or
        // reformatting changes here

        // Start preview with new settings
        try {
            camera.setPreviewDisplay(surfaceHolder);

            // Update the camera parameters
            Camera.Parameters cameraParameters = camera.getParameters();
            cameraParameters.setPreviewSize(w, h);

            camera.setParameters(cameraParameters);
            camera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    public void setCamera(Camera camera) {
        this.camera = camera;
    }
}