0 Replies - 550 Views - Last Post: 17 June 2017 - 06:45 AM

#1 Jeet.in  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 12
  • View blog
  • Posts: 308
  • Joined: 30-May 11

Camera is being used after Camera.release() was called

Posted 17 June 2017 - 06:45 AM

So I am showing front and back camera preview inside a view and I am trying to switch the previews (from front to back and then again front after every 2 seconds) and whatever I may try, I am failing with he following exception. Here is the code where I try to switch the views (is it even the right place to make the switch between the cameras?):

Exception:

06-17 15:09:57.470 4669-4669/com.triple.m.crabzilla.pepers E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.triple.m.crabzilla.pepers, PID: 4669
java.lang.RuntimeException: Camera is being used after Camera.release() was called
 at android.hardware.Camera.setPreviewSurface(Native Method)
 at android.hardware.Camera.setPreviewDisplay(Camera.java:652)
 at com.triple.m.crabzilla.pepers.PersonalExamples.CameraExample$CameraPreview.switchCamera(CameraExample.java:173)
 at com.triple.m.crabzilla.pepers.PersonalExamples.CameraExample$CameraPreview.access$100(CameraExample.java:149)
 at com.triple.m.crabzilla.pepers.PersonalExamples.CameraExample$CameraPreview$1.run(CameraExample.java:187)
 at android.os.Handler.handleCallback(Handler.java:751)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:154)
 at android.app.ActivityThread.main(ActivityThread.java:6776)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)


And here is the code for the same. I think the `cleanup()` routine is creating the problem:

public class CameraExample extends AnimatedViewContainer {

    private final static String TAG = "CameraExample";

    private Camera mCamera;
    private CameraPreview mPreview;
    private Context mContext;
    public int camIter = 1;

    public CameraExample(Context context, int i) {
        super(context, i);

        mPreview = null;
        mContext = context;

        initCamera(context);
    }

    private void initCamera(Context context) {

        // Check if this device has a camera
        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {

            // No camera on this device
            Log.d("Camera", "CameraExample: " + "this device has no camera");
        } else {

            // This device has a camera
            int numCameras = Camera.getNumberOfCameras();
            if (numCameras >= 1) {

                switch (camIter) {
                    case 1:
                        for (int cameraId = 1; cameraId < numCameras; cameraId++) {

                            mCamera = getCameraInstance(cameraId);
                            if (mCamera != null) {
                                CameraInfo cameraInfo = new CameraInfo();
                                Camera.getCameraInfo(cameraId, cameraInfo);
                                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                                    try {

                                        //Create our Preview view and set it as the content of this LinearLayout View
                                        mPreview = new CameraPreview(context, mCamera, cameraId);
                                    } catch (RuntimeException e) {
                                        Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
                                    }
                                }
                                if (createView() == false) {
                                    break;
                                }
                            }
                        }
                        break;
                    case 2:
                        for (int cameraId = 0; cameraId < 1; cameraId++) {
                            mCamera = getCameraInstance(cameraId);
                            if (mCamera != null) {
                                CameraInfo cameraInfo = new CameraInfo();
                                Camera.getCameraInfo(cameraId, cameraInfo);
                                if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                                    try {

                                        //Create our Preview view and set it as the content of this LinearLayout View
                                        mPreview = new CameraPreview(context, mCamera, cameraId);
                                    } catch (RuntimeException e) {
                                        Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
                                    }
                                }
                                if (createView() == false) {
                                    break;
                                }
                            }
                        }
                        break;
                }
            }
        }
    }

    //A safe way to get an instance of the Camera object.
    public static Camera getCameraInstance(int cameraId) {
        Camera c = null;
        try {
            // attempt to get a Camera instance
            c = Camera.open(cameraId);
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
            Log.d(TAG, "CameraExample: " + "camera not available (in use or does not exist); " + e.getMessage());
        }

        // returns null if camera is unavailable
        return c;
    }

    @Override
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) {
        containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false);
        FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview);

        // set camera preview
        if (camIter == 1) {
            previewFrame.addView(mPreview);
        }
        if (camIter == 2) {
            previewFrame.addView(mPreview);
        }

    }

    @Override
    public void cleanup() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mPreview.getHolder().removeCallback(mPreview);
            mCamera.release();
            mCamera = null;
        }
    }

    // A basic Camera preview class
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

        private Context mContext;
        private SurfaceHolder mHolder;
        private Camera mCamera;
        private int mCameraId;

        public CameraPreview(Context context, Camera camera, int cameraId) {
            super(context);
            mContext = context;
            mCamera = camera;
            mCameraId = cameraId;

            // Install a SurfaceHolder. Callback so we get notified when the underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
        }

        private void switchCamera(SurfaceHolder holder) throws IOException {
            cleanup();
            initCamera(getContext());
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
            camIter = camIter == 1 ? 2 : 1;
        }

        @Override
        public void surfaceCreated(final SurfaceHolder holder) {

            final Handler h = new Handler();
            final int delay = 5000; //milliseconds
            //action will perform every two seconds
            h.postDelayed(new Runnable(){
                public void run(){
                    try {
                        switchCamera(holder);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    h.postDelayed(this, delay);
                }
            }, delay);
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // empty. Take care of releasing the Camera preview in your activity.
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.

            if (mHolder.getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // stop preview before making changes
            try {
                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }


            // set preview size
            Camera.Parameters cameraParameters = mCamera.getParameters();
//TODO!!!
            Log.d(TAG, "abc " + cameraParameters.getPreviewSize().height + " " + cameraParameters.getPreviewSize().width);
            List<Size> previewSizes = cameraParameters.getSupportedPreviewSizes();
            for (int i = 0; i < previewSizes.size(); i++) {
                Log.d("Camera", "cam abc: " + previewSizes.get(i).height + " " + previewSizes.get(i).width);
            }
            cameraParameters.setPreviewSize(previewSizes.get(5).width, previewSizes.get(5).height);
            Log.d(TAG, "abc " + cameraParameters.getPreviewSize().height + " " + cameraParameters.getPreviewSize().width);


            // set correct orientation for preview
            CameraInfo info = new CameraInfo();
            Camera.getCameraInfo(mCameraId, info);
            WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            int rotation = windowManager.getDefaultDisplay().getRotation();
            int degrees = 0;
            switch (rotation) {
                case Surface.ROTATION_0:
                    degrees = 0;
                    break;
                case Surface.ROTATION_90:
                    degrees = 90;
                    break;
                case Surface.ROTATION_180:
                    degrees = 180;
                    break;
                case Surface.ROTATION_270:
                    degrees = 270;
                    break;
            }

            int result;
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                result = (info.orientation + degrees) % 360;
                result = (360 - result) % 360;  // compensate the mirror
            } else {  // back-facing
                result = (info.orientation - degrees + 360) % 360;
            }
            mCamera.setDisplayOrientation(result);
            // start preview with new settings
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
            } catch (Exception e) {
                Log.d(TAG, "CameraExample" + "Error starting camera preview: " + e.getMessage());
            }
        }


    }
}



What am I doing wrong? Is this because of the orientation change? Thanks!

This post has been edited by Jeet.in: 17 June 2017 - 07:00 AM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1