简体   繁体   English

自定义Android相机onResume Crash

[英]Custom Camera Android onResume Crash

I have a custom camera application , everything works fine .But whenever the app gets paused (when the onPause or onDestroyed is called) camera is released and afterwards when onResume is called and capture button is clicked is to take an image ,my Application crashes.How do i fix this ? 我有一个自定义的摄像头应用程序,一切正常。但是,每当应用程序暂停(调用onPause或onDestroyed)时,释放摄像头,然后再调用onResume并单击“捕获”按钮拍摄图像时,我的应用程序就会崩溃。我该如何解决 ? Please help me , Thanks in advance 请帮助我,在此先谢谢


CameraActivity Code 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);

            }
        }
        }

Camera Handler Code 相机处理程序代码

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


        }

UPDATE ** StackTrace 更新** 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)

After a lot of research , i finally found out what the problem was . 经过大量研究,我终于发现了问题所在。 Problem was with the FrameLayout , i had to remove it on Pause and recreate it on OnResume 问题出在FrameLayout上,我不得不在暂停时将其删除,并在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);

}

** EDIT ** **编辑**
i also removed the execution of cameraAsync from onCreate , that means i instantiate the camera only in OnResume 我还从onCreate中删除了cameraAsync的执行,这意味着我仅在OnResume中实例化了摄像头

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM