本文介绍了Android Camera Preview 在相机之间切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to switch between the device's Front and Back Camera while showing the camera preview. I am following the sample provide by common ware. Below is the code which I am using. Whenever I click on the Flip button, the surface view goes black, and I don't know where I am going wrong. I have tried to restart the current activity, but I don't want like that.

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

推荐答案

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

You seem to have forgotten to call setPreviewDisplay() (or, in your case, initPreview()) before calling startPreview() from your restartPreviev() method. Effectively, you're trying to start preview without specifying a surface to render the preview into.

这篇关于Android Camera Preview 在相机之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 17:42