使用surfaceview的Android相机预览

时间:2011-12-24 15:52:23

标签: android

我正在尝试在相机预览上画一些东西。但是当程序调用startPreview方法时,它会抛出此异常:java.lang.RuntimeException:startPreview failed。

我的代码:

public class ScanView extends SurfaceView implements SurfaceHolder.Callback {

private MySurfaceThread thread;

Camera camera;

Context context;

private boolean inPreview = false;

public class MySurfaceThread extends Thread {

    private SurfaceHolder myThreadSurfaceHolder;
    private ScanView myThreadSurfaceView;
    private boolean myThreadRun = false;

    public MySurfaceThread(SurfaceHolder surfaceHolder, ScanView surfaceView) {
        myThreadSurfaceHolder = surfaceHolder;
        myThreadSurfaceView = surfaceView;
    }

    public void setRunning(boolean b) {
        myThreadRun = b;
    }

    @Override
    public void run() {

        while (myThreadRun) {
            Canvas c = null;
            try {
                c = myThreadSurfaceHolder.lockCanvas(null);
                synchronized (myThreadSurfaceHolder) {

                    myThreadSurfaceView.onDraw(c);
                }
            } finally {
                if (c != null) {
                    myThreadSurfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}

@Override
protected void onDraw(Canvas canvas) {

}

@Override
public boolean onTouchEvent(MotionEvent event) {

    return true;
}

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

    this.context = context;
    init();
}

private void init() {
    getHolder().addCallback(this);
    thread = new MySurfaceThread(getHolder(), this);


    setFocusable(true); // make sure we get key events

}

public void surfaceChanged(SurfaceHolder arg0, int format, int width, int height) {

    ((Activity)context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    this.

    camera.setDisplayOrientation(90);
    camera.startPreview();
    inPreview = true;
}

public void surfaceCreated(SurfaceHolder arg0) {
    thread.setRunning(true);
    thread.start();

    try {
        camera.setPreviewDisplay(this.getHolder());
    } catch (Throwable t) {
    }
}

public void surfaceDestroyed(SurfaceHolder arg0) {

    boolean retry = true;
    thread.setRunning(false);
    while (retry) {
        try {
            thread.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}

public void onPause() {
    if (inPreview) {
        camera.stopPreview();
    }

    camera.release();
    camera = null;
    inPreview = false;

}

public void onResume() {
    camera = Camera.open();
}
}

我该怎么做?

2 个答案:

答案 0 :(得分:0)

您无法确定只调用一次surfaceChanged()。所以camera.startPreview();那里也可以叫几次。这不对。

答案 1 :(得分:0)

Android的相机在订购方面非常具体。请参阅here并逐步进行操作。我个人追踪它的开始/停止状态。

if (_previewRunning) camera.stopPreview();
[...]
camera.startPreview();