4

我试图在显示相机预览时在设备的前置和后置摄像头之间切换。我正在关注普通商品提供的样本。下面是我正在使用的代码。每当我单击翻转按钮时,表面视图都会变黑,我不知道我哪里出错了。我试图重新开始当前的活动,但我不想那样。

package com.commonsware.android.camera;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Toast;
import android.widget.ToggleButton;
public class PreviewDemo extends Activity {
    private SurfaceView preview = null;
    private SurfaceHolder previewHolder = null;
    private Camera camera = null;
    private boolean inPreview = false;
    private boolean cameraConfigured = false;
    private ToggleButton flipCamera;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    flipCamera = (ToggleButton) findViewById(R.id.flip);
    preview = (SurfaceView) findViewById(R.id.preview);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    flipCamera.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            // TODO Auto-generated method stub
            restartPreview(isChecked);
        }
    });

}

@Override
public void onResume() {
    super.onResume();

    // camera=Camera.open();
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    if (Camera.getNumberOfCameras() > 1
            && camId < Camera.getNumberOfCameras() - 1) {
        // startCamera(camId + 1);
        camera = Camera.open(camId + 1);
    } else {
        // startCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
        camera = Camera.open(camId);
    }
    startPreview();
}

void restartPreview(boolean isFront) {
    if (inPreview) {
        camera.stopPreview();
    }
    //
    camera.release();

    // camera=null;
    // inPreview=false;
    // /*int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    // if (Camera.getNumberOfCameras() > 1 && camId <
    // Camera.getNumberOfCameras() - 1) {
    // //startCamera(camId + 1);
    // camera = Camera.open(camId + 1);
    // } else {
    // //startCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
    // camera = Camera.open(camId);
    // }*/
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
    if (isFront) {
        camera = Camera.open(camId);
        camera.startPreview();

    } else {
        camera = Camera.open(camId + 1);
        camera.startPreview();

    }
    // startPreview();
}

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

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

    super.onPause();
}

private Camera.Size getBestPreviewSize(int width, int height,
        Camera.Parameters parameters) {
    Camera.Size result = null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
        if (size.width <= width && size.height <= height) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;

                if (newArea > resultArea) {
                    result = size;
                }
            }
        }
    }

    return (result);
}

private void initPreview(int width, int height) {
    if (camera != null && previewHolder.getSurface() != null) {
        try {
            camera.setPreviewDisplay(previewHolder);
        } catch (Throwable t) {
            Log.e("PreviewDemo-surfaceCallback",
                    "Exception in setPreviewDisplay()", t);
            Toast.makeText(PreviewDemo.this, t.getMessage(),
                    Toast.LENGTH_LONG).show();
        }

        if (!cameraConfigured) {
            Camera.Parameters parameters = camera.getParameters();
            Camera.Size size = getBestPreviewSize(width, height, parameters);

            if (size != null) {
                parameters.setPreviewSize(size.width, size.height);
                camera.setParameters(parameters);
                cameraConfigured = true;
            }
        }
    }
}

private void startPreview() {
    if (cameraConfigured && camera != null) {

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

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        // no-op -- wait until surfaceChanged()
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        initPreview(width, height);
        startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // no-op
        if (camera != null) {
            /*
             * Call stopPreview() to stop updating the preview surface.
             */
            camera.stopPreview();

            /*
             * Important: Call release() to release the camera for use by
             * other applications. Applications should release the camera
             * immediately in onPause() (and re-open() it in onResume()).
             */
            camera.release();

            camera = null;
        }
    }
};
}
4

1 回答 1

12

在从您的方法调用之前,您似乎忘记了调用setPreviewDisplay()(或者,在您的情况下,initPreview()) 。实际上,您正在尝试在没有指定要渲染预览的表面的情况下开始预览。startPreview()restartPreviev()

于 2012-07-02T14:23:40.443 回答