2

I have this code for my app, it doesn't show any errors but everytime I run it on my phone, it crashes. Anybody have idea about this? Thanks

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

        }*/
}
hectichavana
  • 1,436
  • 13
  • 41
  • 71

3 Answers3

4

Do you know where the error is actually occurring (i.e. what output are you seeing in the logcat window?)

My wild guess is that it's this line causing the problem:

p.setPreviewSize(w, h)

You can only set the preview size to one of the sizes that your device supports - check the getSupportedPreviewSizes() method in Camera.Parameters and choose the closest match for your view:

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

(code above from @seantron: Picture distorted with Camera and getOptimalPreviewSize)

Community
  • 1
  • 1
Scottie
  • 545
  • 4
  • 14
  • I dont face any errors with my emulator, only when I mount the app to my device. So I should add that method and then call instead of setPreviewSize or what? When I'm triying to write the method, there's an error with 'camera.getParameters();' – hectichavana May 03 '11 at 10:42
  • The emulator isn't fussy about the preview size, it will essentially emulate whatever you ask for. Replace camera with mCamera in the snippet above, then call this method before you call setPreviewSize. You want to call setPreviewSize with the result returned from getBestPreviewSize, i.e. setPreviewSize(result.width, result.height) – Scottie May 03 '11 at 11:09
  • I got an error for calling these methods; p.getBestPreviewSize(w, h); p.setPreviewSize(result.w, result.h); any idea? – hectichavana May 03 '11 at 11:52
  • The bestPreviewSize method above needs to be copied into your class; it's not a method on Camera.Parameters. Your code would look something like `Camera.Size bestSize = bestPreviewSize(w, h);`, followed by `p.setPreviewSize(bestSize.w, bestSize.h);` – Scottie May 03 '11 at 12:26
  • I've updated my code as what you've suggested, no errors found but the app crashed.. hmmm what do you think? – hectichavana May 03 '11 at 12:52
  • Difficult to know without further info. Put a breakpoint in on the line `p.setPreviewSize(bestSize.width, bestSize.height);` and then step over the lines of code until your app crashes so you can pinpoint the actual line causing the problem. Check the logcat window in the Debug perspective for errors in red - some of the lines should explain why the app is crashing. btw, what version/API Level of Android are you targeting, and on what hardware? – Scottie May 03 '11 at 14:17
  • my logcat shows that the crash is caused by this line: 'for (Camera.Size size : p.getSupportedPreviewSizes())' then it's followed by 'Camera.Size bestSize = getBestPreviewSize(w, h);' I'm still testing on the emulator anyway, API Level 7 – hectichavana May 03 '11 at 14:37
  • Apparently getSupportedPreviewSizes can return null on the emulator, even though the spec says that at least one preview size should always be returned. Try putting in and IF statement to skip the code to set best preview size when no supported preview sizes are returned, or just trying running the code on your phone. – Scottie May 04 '11 at 07:37
  • Thanks much it's working on my phone, but the view was just a little bit weird. You can look it up here: http://yfrog.com/gyz4q1j maybe you understand where the problem is – hectichavana May 05 '11 at 08:18
  • That's because the camera display is rotated 90 degrees, I think by default it assumes the camera is being used in landscape mode rather than portrait. One way to rectify this is to call `mCamera.setDisplayOrientation(90);`, however there appear to be subsequent side effects when you attempt to save a bitmap image: [link](http://stackoverflow.com/q/5859876/734758) – Scottie May 06 '11 at 11:19
  • okay I'm gonna try to call the method. No dont worry I dont use this CameraView not for taking pictures, but for the basic of augmented reality view – hectichavana May 06 '11 at 12:43
1

surround setPreview() of camera with try & catch Block, may this work

  • I got this already try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } it works on emulator but not on the phone, weird :/ – hectichavana Apr 27 '11 at 10:52
  • then sry buddy, i also dnt knw –  Apr 27 '11 at 10:54
0

I had a similar issue, and the cause was the implementation of the surfaceDestroyed(SurfaceHolder holder) method. When I commented out the code, all was well.

BluJ IT
  • 369
  • 3
  • 12