Android - 相机表面出错

时间:2011-04-27 10:33:17

标签: android android-camera

我有我的应用程序的代码,它没有显示任何错误,但每次我在手机上运行它,它崩溃。 有人对此有所了解吗?感谢

public class CameraView extends Activity implements SurfaceHolder.Callback,OnClickListener {
        static final int FOTO_MODE = 0;
        private static final String TAG = "CameraTest";
        Camera mCamera;
        boolean mPreviewRunning = false;
        private Context mContext = this;

        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);

            Log.e(TAG, "onCreate");

            Bundle extras = getIntent().getExtras();

            getWindow().setFormat(PixelFormat.TRANSLUCENT);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.camera_surface);
            mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
            mSurfaceView.setOnClickListener(this);
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        //private SurfaceView mSurfaceView;
        //private SurfaceHolder mSurfaceHolder;

        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
        }

        Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
            public void onPictureTaken(byte[] imageData, Camera c) {

                if (imageData != null) {

                    Intent mIntent = new Intent();

                    StoreByteImage(mContext, imageData, 50,
                            "ImageName");
                    mCamera.startPreview();

                    setResult(FOTO_MODE, mIntent);
                    finish();

                }
            }
        };

        protected void onResume() {
            Log.e(TAG, "onResume");
            super.onResume();
        }

        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
        }

        protected void onStop() {
            Log.e(TAG, "onStop");
            super.onStop();
        }

        public void surfaceCreated(SurfaceHolder holder) {
            Log.e(TAG, "surfaceCreated");
            mCamera = Camera.open();

        }

        private Camera.Size getBestPreviewSize(int width, int height)
        {
            Camera.Size result=null;    
            Camera.Parameters p = mCamera.getParameters();
            for (Camera.Size size : p.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;
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            Log.e(TAG, "surfaceChanged");

            // XXX stopPreview() will crash if preview is not running
            if (mPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters p = mCamera.getParameters();
            Camera.Size bestSize = getBestPreviewSize(w, h);
            p.setPreviewSize(bestSize.width, bestSize.height);
            mCamera.setParameters(p);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.e(TAG, "surfaceDestroyed");
            mCamera.stopPreview();
            mPreviewRunning = false;
            mCamera.release();
        }

        private SurfaceView mSurfaceView;
        private SurfaceHolder mSurfaceHolder;

        public void onClick(View arg0) {

            mCamera.takePicture(null, mPictureCallback, mPictureCallback);

        }

        public static boolean StoreByteImage(Context mContext, byte[] imageData,
                int quality, String expName) {

            File sdImageMainDirectory = new File("/sdcard");
            FileOutputStream fileOutputStream = null;
            String nameFile;
            try {

                BitmapFactory.Options options=new BitmapFactory.Options();
                options.inSampleSize = 5;

                Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,
                        imageData.length,options);


                fileOutputStream = new FileOutputStream(
                        sdImageMainDirectory.toString() +"/image.jpg");


                BufferedOutputStream bos = new BufferedOutputStream(
                        fileOutputStream);

                myImage.compress(CompressFormat.JPEG, quality, bos);

                bos.flush();
                bos.close();

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return true;
        }

        /*@Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceChanged");

            // XXX stopPreview() will crash if preview is not running
            if (mPreviewRunning) {
                mCamera.stopPreview();
            }

            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
                mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;
        }

        @Override
        public void surfaceCreated(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceCreated");
            mCamera = Camera.open();

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder arg0) {
            // TODO Auto-generated method stub
            Log.e(TAG, "surfaceDestroyed");
            mCamera.stopPreview();
            mPreviewRunning = false;
            mCamera.release();

        }*/
}

3 个答案:

答案 0 :(得分:4)

您知道错误实际发生的位置(即您在logcat窗口中看到了什么输出?)

我的猜测是这条线导致了这个问题:

p.setPreviewSize(w, h)

您只能将预览尺寸设置为设备支持的尺寸之一 - 检查Camera.Parameters中的getSupportedPreviewSizes()方法,并为您的视图选择最接近的匹配项:

private Camera.Size getBestPreviewSize(int width, int height)
{
    Camera.Size result=null;    
    Camera.Parameters p = camera.getParameters();
    for (Camera.Size size : p.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;
}

(上面的代码来自@seantron:Picture distorted with Camera and getOptimalPreviewSize

答案 1 :(得分:1)

带有try&amp; amp;相机的环绕setPreview()抓住Block,可能会这样做

答案 2 :(得分:0)

我遇到了类似的问题,原因是SurfaceDestroyed(SurfaceHolder holder)方法的实现。当我评论出代码时,一切都很好。