Android应用相机预览停止工作(使用已弃用的`setType`方法)

时间:2016-05-10 12:26:39

标签: android android-camera

我有一个相机预览有效的相机应用程序。该应用程序是在几年前(2012年)开发的,我决定重用其部分代码,但是,经过再次测试(在相同的硬件i9100上,不同的OS 4.4与3.0),我的相机预览图像有问题

enter image description here

当我移动手机时,我看到图像发生变化,它会响应明暗模式(因此应用程序正在与相机通信)。

这是我的代码(它使用弃用的方法setType):

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

SurfaceHolder mHolder;
public Camera camera;
public final String fileName = "/download/CameraGPS/zdelTempPhotoPreview.jpg";

CameraPreview(Context context) {
    super(context);
    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    camera = Camera.open();
    Parameters parameter02 = camera.getParameters();
    parameter02.setJpegThumbnailSize(80, 60);
    parameter02.setPictureSize(640, 480);
    camera.setParameters(parameter02);
    try {
        camera.setPreviewDisplay(holder);
        camera.setDisplayOrientation(90);
        Parameters parameters00 = camera.getParameters();
        //parameters00.setRotation(90);
        //parameters00.setFlashMode("on");
        //parameters00.setJpegQuality(20);
        camera.setParameters(parameters00);

        camera.setPreviewCallback(new PreviewCallback() {

            public void onPreviewFrame(byte[] data, Camera arg1) {
                CameraPreview.this.invalidate();
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    // Because the CameraDevice object is not a shared resource, it's very
    // important to release it when the activity is paused.
    camera.stopPreview();
    camera = null;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.

    //camera.getParameters().setRotation();
    //camera.getParameters().setJpegQuality(20);
    //camera.getParameters().setPictureSize(width, height)

    Parameters parameters = camera.getParameters();
    parameters.setPreviewSize(w, h);
    camera.setParameters(parameters);
    camera.startPreview();
}

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);

    Log.w(TAG,"clicked in preview");
    Paint p = new Paint(Color.RED);
    Log.d(TAG, "draw");
    canvas.drawText("PREVIEW", canvas.getWidth() / 2,
            canvas.getHeight() / 2, p);
}

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您无法将图片大小和预览大小设置为任意值。确保分别检查getSupportedPictureSizes()和getSupportedPreviewSizes()返回的列表。

经常(我不记得这是否适用于三星Galaxy S2),当图片的宽高比与预览的宽高比不同时,相机无法正常工作。

此外,您不应该在预览表面上绘图,而且绝对不能从onPreviewFrame()回调中绘制。

答案 1 :(得分:1)

首先要在camera.setPreviewDisplay(holder)方法中添加surfaceChanged()

<强>更新 请在surfaceCreatedsurfaceChanged holder.getSurface() != null进行调试 此外,您应该在camera.release()中添加surfaceDestroyed,然后清理安装应用(首先卸载然后重新安装应用)。自上次运行应用程序以来,相机服务可能会挂起。

更新2: 我刚刚注意到你错过了从SurfaceHolder和surfaceChanged()方法传递的surfaceCreated()注册的回调。在这种情况下,有意义的是从未达到surfaceChanged(),这意味着从未实际调用startPreview()..

surfaceCreatedsurfaceChanged方法中,请更新代码以包含:

    mHolder.removeCallback(this); // unregister from old SurfaceHolder
    holder.addCallback(this); // register to new holder
    try {
        camera.setPreviewDisplay(holder);
    } catch (IOException e) {
        e.printStackTrace();
    }
    mHolder = holder;