【问题标题】:CameraView only works in emulatorCameraView 仅适用于模拟器
【发布时间】:2012-08-23 08:41:31
【问题描述】:

阅读本教程后,我编写了一个小相机应用程序:

http://www.brighthub.com/mobile/google-android/articles/43414.aspx

在模拟器中一切正常(好吧,没有摄像头,但至少没有错误;))

然后我尝试让它在我的 HTC Wildfire S 上运行。但启动后应用程序立即崩溃。

这是我的Activity的代码,也许有人有想法,如何解决这个问题:

public class CameraView extends Activity implements SurfaceHolder.Callback {

    android.hardware.Camera mCamera;
    boolean mPreviewRunning = false;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.camera_surface);
        SurfaceView mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera);
        SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera = android.hardware.Camera.open();
    }


    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        if(mPreviewRunning) {
            mCamera.stopPreview();
        }

        android.hardware.Camera.Parameters params = mCamera.getParameters();
        params.setPreviewSize(width, height);
        mCamera.setParameters(params);

        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        mCamera.startPreview();
        mPreviewRunning = true;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mPreviewRunning = false;
        mCamera.release();
    }

    android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, android.hardware.Camera camera) {

        }
    };
}

【问题讨论】:

  • 崩溃的 logcat 输出是什么?
  • 它不会在模拟器中崩溃。仅在我的设备上。有没有办法通过 LogCat 输出直接在手机上调试?
  • 好吧,USB-Debugging 终于成功了 ;) 第一个错误是 RuntimeException: "setParameters failed"
  • 问题是“PreviewSize”。当我用“params.setPreviewSize(width, height);”删除行时它工作正常。你有什么想法,为什么会出现这个问题?

标签: java android eclipse android-emulator


【解决方案1】:

您遇到了异常,因为您试图让相机使用它不支持的宽度和高度。您要求它使用 SurfaceView 的宽度和高度,这很少与支持的预览尺寸之一匹配。相反,请尝试使用以下内容:

   public class CameraView extends Activity implements SurfaceHolder.Callback {

android.hardware.Camera mCamera;
boolean mPreviewRunning = false;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    getWindow().setFormat(PixelFormat.TRANSLUCENT);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.camera_surface);
    SurfaceView mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera);
    SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.addCallback(this);
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
        mCamera.setPreviewDisplay(previewHolder);   
    }
    catch (Throwable t) {
        Log.e(TAG, "Exception in setPreviewDisplay()", t);
    }
}


@Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Camera.Parameters parameters=camera.getParameters();
    Camera.Size size=getBestPreviewSize(width, height, parameters);

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

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    mCamera.stopPreview();
    mPreviewRunning = false;
    mCamera.release();
}

android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, android.hardware.Camera camera) {

    }
};

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

此代码全部改编自我为我的书编写的代码。我更改了您的一些代码,因此可能需要修复一些变量名和导入,但它应该可以正常工作。

getBestPreviewSize() 是这里的神奇方法,它计算要使用的最佳和最佳相机预览尺寸。

【讨论】:

  • 不错的解决方案。非常感谢!但是你有没有想法,如何旋转我可以在纵向模式下看到的相机预览?
  • 只传递宽度作为高度,高度作为宽度。此外,在清单中将 Activity 的屏幕方向声明为纵向。
  • 预览的旋转还是不正确。我尝试使用“setRotation”,但没有任何变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多