Android相机+陀螺仪/加速度计应用程序在拍照时崩溃

时间:2016-11-27 07:11:14

标签: android image camera

我已经通过很多链接寻找解决方案,但这是我在Android中的第一个官方应用。我已经制作了像计算器这样的其他小类,但没有像这样,所以即使我阅读它们,我也无法理解建议和解决方案。

该应用程序基本上执行以下操作: -

  1. 接受陀螺仪和加速计读数
  2. 计算用户在圆圈中移动时的运动角度。
  3. 每10度拍摄一次图像。
  4. 第一个类适用于曲面视图。第二个是拍摄照片和计算传感器读数

    我已经制定了前两部分。但第三部分是问题。 每次拍摄图像时,应用程序都会挂起,表面视图会停止工作。没有任何反应。当我再旋转10度时,应用程序崩溃了。

    有人可以告诉我我做错了什么。提前谢谢。

    package com.example.mehta.accelerometerin;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.graphics.Bitmap;
    import android.hardware.Camera;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorManager;
    import android.net.Uri;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.hardware.SensorEventListener;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.FrameLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import static android.content.ContentValues.TAG;
    import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
    import static java.lang.Math.sqrt;
    
    
    
    
    
    
    
    class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;
    
    
    
    
        private boolean checkCameraHardware(Context context) {
            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
                // this device has a camera
                return true;
            } else {
                // no camera on this device
                return false;
            }
        }
    
    
    
    
        public CameraPreview(Context context, Camera camera) {
            super(context);
            mCamera = camera;
    
    
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    
    
        public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, now tell the camera where to draw the preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
            // 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 and make any resize, rotate or
            // reformatting changes here
    
            // start preview with new settings
            try {
                mCamera.setPreviewDisplay(mHolder);
                mCamera.setDisplayOrientation(90);
                mCamera.startPreview();
    
            } catch (Exception e) {
                Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
    
        }
    
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
    
        }
    
    
    }
    
    
    class MainActivity extends AppCompatActivity implements SensorEventListener {
        private Camera mCamera;
        private CameraPreview mPreview;
    
        private SensorManager senSensorManager;
        private Sensor senAccelerometer;
        private Sensor senGyroscope;
        private long lastUpdate = 0;
        private float last_x, last_y, last_z;
        private static final int SHAKE_THRESHOLD = 600;
        TextView tv1, tv2, tv3, tv4, tv5;
        int j = 0;
        int i = 1;
        int l = 10;
        int m = 0;
        private float xg, yg, zg, xa, ya, za;
        private float x1, y1;
        float x2, y2;
        private float xang, yang, zang;
        private float zacc;
        private float xacc;
        private float yacc;
        private int greset;
        public static Camera getCameraInstance() {
            Camera c = null;
            try {
                c = Camera.open(); // attempt to get a Camera instance
            } catch (Exception e) {
                // Camera is not available (in use or does not exist)
            }
            return c; // returns null if camera is unavailable
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Create an instance of Camera
            mCamera = getCameraInstance();
    
            // Create our Preview view and set it as the content of our activity.
            mPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
            preview.addView(mPreview);
            greset = 0;
            senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
            senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            senGyroscope = senSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
    
            senSensorManager.registerListener(this,senAccelerometer,SensorManager.SENSOR_DELAY_NORMAL);
            senSensorManager.registerListener(this,senGyroscope,SensorManager.SENSOR_DELAY_NORMAL);
    
    
        }
    
    
    
        public static final int MEDIA_TYPE_IMAGE = 1;
        public static final int MEDIA_TYPE_VIDEO = 2;
    
        /** 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), "MyCameraApp");
            // 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;
        }
    
        private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
    
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                Toast.makeText(getApplicationContext(), "on Picture Taken", Toast.LENGTH_SHORT).show();
    
                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());
                }
            }
        };
    
    
    
        protected void onPause() {
            super.onPause();
            senSensorManager.unregisterListener(this);
    
        }
    
        protected void onResume() {
            super.onResume();
            senSensorManager.registerListener(this,senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
            senSensorManager.registerListener(this,senGyroscope,SensorManager.SENSOR_DELAY_NORMAL);
        }
    
    
        public void onSensorChanged(SensorEvent sensorEvent) {
            Sensor mySensor = sensorEvent.sensor;
    
    
            if (mySensor.getType() == Sensor.TYPE_GYROSCOPE) {
                greset ++;
                zg += sensorEvent.values[1];
                xg +=sensorEvent.values[0];
                yg +=sensorEvent.values[2];
                if(zg>30)
                {
                    zg=0;
                }
                if(xg>30)
                {
                    xg=0;
                }
                if(yg>30)
                {
                    yg=0;
                }
                xang = xg*12;
                yang = yg*12;
                zang = zg*12;
                if(zang>=l) {
                    Toast.makeText(getApplicationContext(), "click="+i, Toast.LENGTH_SHORT).show();
                    mCamera.stopPreview();
                    mCamera.takePicture(null,null,mPicture);
                    mCamera.startPreview();
                    l += 10;
                    i++;}
    
    
    
    
                if (greset >10)
                {
                    xg +=0.1;
    
                    greset = 0;
                }
    
            }
    
            if(mySensor.getType()==Sensor.TYPE_ACCELEROMETER)
            {
                xa = sensorEvent.values[0];
                za = sensorEvent.values[1];
                ya = sensorEvent.values[2];
    
    
    
                zacc = (float)(za - (((90 -  xang)/ 90) * 9.8));
    
    
            }
    
    
    
            if (l > 360) {
                l = 10;
            }
        }
    
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
    
        }
    
        public int returnvalue(){
            return(i);
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

  1. 在致电stopPreview()之前不要立即致电takePicture()This method is only valid when preview is active (after startPreview()). Preview will be stopped after the image is taken

  2. 您应该从startPreview()致电onPictureTaken(),而不是在致电takePicture()后立即致电。

  3. 在单独的处理程序线程上打开相机,而不是在主(UI)线程上打开。

  4. 您的代码可能存在其他问题,但让我们从修复这三个直接问题开始。