自定义相机Android onResume崩溃

时间:2016-02-01 10:35:36

标签: java android android-camera

我有一个自定义相机应用程序,一切正常。但是每当应用程序被暂停时(当调用onPause或onDestroyed时)相机被释放,之后当调用onResume并且点击捕获按钮是拍摄图像时,我的应用程序崩溃。我该怎么解决这个问题?请帮助我,提前致谢

CameraActivity代码

package com.example.skmishra.plates.Activities;

    import android.app.ActionBar;
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.hardware.Camera;
    import android.hardware.SensorManager;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.OrientationEventListener;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.widget.ZoomControls;

    import com.example.skmishra.plates.Asyncs.CameraAsync;
    import com.example.skmishra.plates.CameraHandler;
    import com.example.skmishra.plates.Library.Fonts;
    import com.example.skmishra.plates.R;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.FilenameFilter;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.SortedSet;
    import java.util.TreeSet;

    /**
     * Created by skmishra on 12/28/2015.
     */
    public class camera extends Activity {

        private static final int RESULT_LOAD_IMAGE = 200 ;
        private Camera mCamera=null;
        private CameraHandler surface_view;
        public static final int MEDIA_TYPE_IMAGE = 1;
        public static final int MEDIA_TYPE_VIDEO = 2;
        public static final String TAG = "Aloo";
        int toRotate = 90;
        public int currentCameraID = 0;
        OrientationEventListener myOrientationEventListener;
        private ZoomControls zoomControls;
        private double mDist;
        Boolean imageSwitchClicked = false;
        Boolean mShowFlash = false;
        ImageView mSwitch_cam;
        ImageView mFlashBut;
        FrameLayout preview;
        CameraAsync mCamAsync;
        ImageView imageGallery;
        TextView raleway;
        TextView headerCameraText;
        Fonts mFonts;
        int permCode=4;
        Camera.Parameters params;
        String recievedType=null;
        @Override

        protected void onCreate(Bundle savedInstanceState) {
            Log.e("I Called Thus "," cda");
            mCamAsync=new CameraAsync(this);
            mCamAsync.execute();
            super.onCreate(savedInstanceState);
            setContentView(R.layout.camera);
           imageGallery = (ImageView) findViewById(R.id.select_gallery);
             mFonts = new Fonts();




            preview = (FrameLayout) findViewById(R.id.camera_preview);
            mFlashBut = (ImageView) findViewById(R.id.flash);
                mSwitch_cam = (ImageView) findViewById(R.id.white_switch);
                raleway = (TextView) findViewById(R.id.textView2);
                headerCameraText = (TextView) findViewById(R.id.imageHead);
                // mFonts.setRalewayBold(this, headerCameraText);
                Intent gets = getIntent();
                recievedType = gets.getExtras().getString("recievedCameraPurpose");
                handleHeaderText(recievedType);
                mFonts.setRalewayBold(this, raleway);



            myOrientationEventListener
                    = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {

                @Override
                public void onOrientationChanged(int arg0) {
                    int rotation = arg0;
                    if (rotation > 340) {
                        if (currentCameraID == 0) {
                            toRotate = 90;
                        } else {
                            toRotate =270;
                            Log.e("POSITION_TITLT", "-> Potrait Front camera");
                        }
                    } else if (rotation < 80 && rotation > 30) {
                        toRotate = 180;
                        Log.e("POSITION_TILT", "-> Landscape Right " + rotation);
                    } else if (rotation < 280 && rotation > 240) {
                        toRotate = 0;
                        Log.e("POSITION_TILT", "-> Landscape Left " + rotation);
                    }


                }
            };

            if (myOrientationEventListener.canDetectOrientation()) {
                myOrientationEventListener.enable();
            } else {
                Toast.makeText(this, "Can't DetectOrientation", Toast.LENGTH_LONG).show();
                finish();
            }
        }

        private boolean checkifCamera(Context context) {
            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
                return true;
            } else {
                return false;
            }
        }

        public Camera getCameraInstance() {
            Camera c = null;
            try {
                releaseCameraAndPreview();
                c = Camera.open();
            } catch (Exception e) {
                Toast.makeText(this, "Print error" + e.getMessage(), Toast.LENGTH_LONG).show();

            }
            return c;
        }
       public void onCompleteInstanceCameraAysnc(Camera camera)
       {
           mCamera = camera;
           surface_view = new CameraHandler(this, mCamera);
           params = mCamera.getParameters();
           preview.addView(surface_view);
           set_image_gallery();

       }
        public void switchC(View view) {

            if (!imageSwitchClicked) {
                mSwitch_cam.setAlpha(1.0f);
                imageSwitchClicked = true;
            } else {

                mSwitch_cam.setAlpha(0.5f);
                imageSwitchClicked = false;
            }

            setCameraID();
            mCamera = surface_view.switchCamera();
            params=mCamera.getParameters();



        }

        public void flash_onOf(View view) {

            if (!mShowFlash) {
                params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
                mFlashBut.setAlpha(1.0f);
                mShowFlash = true;
            } else {
                params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                mFlashBut.setAlpha(0.5f);
                mShowFlash = false;
            }
        }

        private void releaseCameraAndPreview() {

            if (mCamera != null) {
                mCamera.stopPreview();
                mCamera.setPreviewCallback(null);
                mCamera.lock();
                mCamera.release();
                mCamera=null;
            }
            else
            {
                Log.e("Cert","Lerts");
            }
        }

        @Override
        protected void onResume() {
            super.onResume();


        }



        @Override
        protected void onDestroy() {
            Log.e("LLL", "Dessssdccc");
            super.onDestroy();
             try {

                mCamera.stopPreview();
                mCamera.setPreviewCallback(null);
                mCamera.lock();
                myOrientationEventListener.disable();
                mCamera.release();
                mCamera=null;
                permCode=15;



            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onPause() {
            Log.e("LLL", "Dessssdccc");
            super.onPause();
            try {

                mCamera.stopPreview();
                mCamera.setPreviewCallback(null);
                mCamera.lock();
                myOrientationEventListener.disable();
                mCamera.release();
                mCamera=null;
                permCode=15;



            } catch (Exception e) {
                e.printStackTrace();
            }
        }


        public void takePH(View view) {


            if(mShowFlash && !imageSwitchClicked)
            {
                params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);

            }


                params.set("rotation", toRotate);

                mCamera.setParameters(params);


            mCamera.takePicture(null, null, mPicture);
        }

        Camera.PictureCallback mPicture = new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
                if (pictureFile == null) {
                    Log.d(TAG, "Error creating media file, check storage permissions: ");
                    return;
                }


                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();


                } catch (FileNotFoundException e) {
                    Log.d(TAG, "File not found: " + e.getMessage());
                } catch (IOException e) {
                    Log.d(TAG, "Error accessing file: " + e.getMessage());
                }
                Intent i=new Intent(getApplicationContext(),ShowOut.class);
                i.putExtra("purpose",recievedType);
                i.putExtra("img-url",pictureFile.toString());
                startActivity(i);
            }
        };


        /**
         * Create a file Uri for saving an image or video
         */
        private static Uri getOutputMediaFileUri(int type) {
            return Uri.fromFile(getOutputMediaFile(type));
        }

        /**
         * Create a File for saving an image or video
         */
        private static File getOutputMediaFile(int type) {
            // To be safe, you should check that the SDCard is mounted
            // using Environment.getExternalStorageState() before doing this.

            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES), "Plates");
            // This location works best if you want the created images to be shared
            // between applications and persist after your app has been uninstalled.

            // Create the storage directory if it does not exist
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d("MyCameraApp", "failed to create directory");
                    return null;
                }
            }

            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File mediaFile;
            if (type == MEDIA_TYPE_IMAGE) {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                        "IMG_" + timeStamp + ".jpg");
            } else if (type == MEDIA_TYPE_VIDEO) {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                        "VID_" + timeStamp + ".mp4");
            } else {
                return null;
            }

            return mediaFile;
        }
        public void handleHeaderText(String type) {
            Log.e("Type",type);
            headerCameraText.setText("");
            if (type.equals("ADD_COVER_PLATES")) {
                headerCameraText.setText("Take a cover image for your plate");

            }
            else if(type.equals("ADD_PROFILE_USER"))
            {
                imageGallery.setVisibility(View.GONE);

            }
            else if(type.equals("PLATE_UPLOAD_SINGLETON")) {
                headerCameraText.setText("Click an image for a plate");

            }

        }

        public void setCameraID() {
            if (currentCameraID == Camera.CameraInfo.CAMERA_FACING_BACK) {

                currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
                toRotate = 270;
            } else {

                currentCameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
                toRotate = 90;
            }
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            // Get the pointer ID
            Camera.Parameters params = mCamera.getParameters();
            int action = event.getAction();


            if (event.getPointerCount() > 1) {
                // handle multi-touch events
                if (action == MotionEvent.ACTION_POINTER_DOWN) {
                    mDist = getFingerSpacing(event);
                } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) {
                    mCamera.cancelAutoFocus();
                    handleZoom(event, params);
                }
            } else {
                // handle single touch events
                if (action == MotionEvent.ACTION_UP) {
                    handleFocus(event, params);
                }
            }
            return true;
        }

        private void handleZoom(MotionEvent event, Camera.Parameters params) {
            int maxZoom = params.getMaxZoom();
            int zoom = params.getZoom();
            double newDist = getFingerSpacing(event);
            if (newDist > mDist) {
                //zoom in
                if (zoom < maxZoom)
                    zoom++;
            } else if (newDist < mDist) {
                //zoom out
                if (zoom > 0)
                    zoom--;
            }
            mDist = newDist;
            params.setZoom(zoom);
            mCamera.setParameters(params);
        }

        public void handleFocus(MotionEvent event, Camera.Parameters params) {
            int pointerId = event.getPointerId(0);
            int pointerIndex = event.findPointerIndex(pointerId);
            // Get the pointer's current position
            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);

            List<String> supportedFocusModes = params.getSupportedFocusModes();
            if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean b, Camera camera) {
                        // currently set to auto-focus on single touch
                    }
                });
            }
        }

        /**
         * Determine the space between the first two fingers
         */
        private double getFingerSpacing(MotionEvent event) {
            // ...
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            double pres;
            pres = Math.sqrt(x * x + y * y);

            return pres;
        }

        public void set_image_gallery() {


            // Find the last picture
            String[] projection = new String[]{
                    MediaStore.Images.ImageColumns._ID,
                    MediaStore.Images.ImageColumns.DATA,
                    MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
                    MediaStore.Images.ImageColumns.DATE_TAKEN,
                    MediaStore.Images.ImageColumns.MIME_TYPE
            };
            final Cursor cursor = getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
                            null,MediaStore.Images.ImageColumns._ID + " DESC");


    // Put it in the image view
            if (cursor.moveToFirst()) {
                String imageLocation = cursor.getString(1);
                File imageFile = new File(imageLocation);

                if (imageFile.exists()) {   // TODO: is there a better way to do this?
                    Bitmap bm=decodeFile(imageFile);

                    imageGallery.setImageBitmap(bm);
                }
            }
            cursor.close();
        }
        public Bitmap decodeFile(File f) {

            try {
                //Decode image size
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(new FileInputStream(f), null, o);

                //The new size we want to scale to
                final int REQUIRED_SIZE = 490;

                //Find the correct scale value. It should be the power of 2.
                int scale = 1;
                while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                    scale *= 2;

                //Decode with inSampleSize
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
            } catch (FileNotFoundException e) {
            }
            return null;
        }
        public void imagePick(View view)
        {
               Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                photoPickerIntent.setType("image/*");

                startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);

            if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {


                Uri selectedImage = data.getData();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};

                Cursor cursor = getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String picturePath = cursor.getString(columnIndex);
                cursor.close();
                Intent transfer=null;
                if(recievedType.equals("ADD_COVER_PLATES")) {
                    transfer = new Intent(this, create_plates.class);
                }
                else if(recievedType.equals("PLATE_UPLOAD_SINGLETON"))
                {
                     transfer=new Intent(this,plate_select_upload.class);
                }
                transfer.putExtra("imagUrl",picturePath);
                startActivity(transfer);

            }
        }
        }

相机处理程序代码

         package com.example.skmishra.plates;

        import android.content.Context;
        import android.hardware.Camera;
        import android.util.Log;
        import android.view.SurfaceHolder;
        import android.view.SurfaceView;

        import java.io.IOException;

        /**
         * Created by skmishra on 12/28/2015.
         */

        public class CameraHandler extends SurfaceView implements SurfaceHolder.Callback {
            private SurfaceHolder mHolder;

            private Camera mCamera=null;
            public int currentCameraID=0;

            public CameraHandler(Context context,Camera camera) {
                super(context);
                mCamera=camera;

                mHolder=getHolder();
                mHolder.addCallback(this);
                mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                try {
                    if(mCamera==null)
                    {
                        mCamera=Camera.open();
                    }
                    mCamera.setPreviewDisplay(holder);

                    Camera.Parameters p = mCamera.getParameters();

                }
                catch (IOException e)
                {
                    Log.d("--DS", "Error setting camera preview: " + e.getMessage());
                }

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                fixOr();
                if(mHolder.getSurface()==null)
                {
                    return;
                }
                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 and make any resize, rotate or
                // reformatting changes here

                // start preview with new settings
                try {
                    mCamera.setPreviewDisplay(mHolder);
                    mCamera.startPreview();

                } catch (Exception e){
                    Log.d("--DS", "Error starting camera preview: " + e.getMessage());
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                // TODO Auto-generated method stub


                mCamera.release();
                mCamera = null;
            }
            public void fixOr()
            {
                mCamera.stopPreview();
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
            }

            public Camera switchCamera()  {

                mCamera.stopPreview();
              mCamera.release();

                if(currentCameraID==Camera.CameraInfo.CAMERA_FACING_BACK)
                {

                    currentCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
                }
                else
                {

                    currentCameraID=Camera.CameraInfo.CAMERA_FACING_BACK;
                }
                mCamera=Camera.open(currentCameraID);
                fixOr();
                try {
                    mCamera.setPreviewDisplay(mHolder);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mCamera.startPreview();
                return mCamera;
            }


        }

更新** StackTrace

 Process: com.example.skmishra.plates, PID: 10575
java.lang.RuntimeException: Fail to connect to camera service
        at android.hardware.Camera.<init>(Camera.java:545)
        at android.hardware.Camera.open(Camera.java:403)
        at com.example.skmishra.plates.CameraHandler.surfaceCreated(CameraHandler.java:35)
        at android.view.SurfaceView.updateWindow(SurfaceView.java:599)
        at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:243)
        at android.view.View.dispatchWindowVisibilityChanged(View.java:9034)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
        at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1275)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1319)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1062)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5873)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5753)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)

1 个答案:

答案 0 :(得分:0)

经过大量研究,我终于找到了问题所在。问题出在FrameLayout上,我不得不在Pause上删除它并在OnResume上重新创建它

 @Override
protected void onResume() {
    super.onResume();
        mCamAsync = new CameraAsync(this);//Async task to get the camera instance
        mCamAsync.execute();



}



@Override
protected void onPause() {
     super.onPause();
    releaseCameraAndPreview();
        preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.removeViewAt(0);

}

**编辑**
我还从onCreate中删除了cameraAsync的执行,这意味着我只在OnResume中实例化相机