我已经编写了一个Android活动作为一个简单的相机,但是当我拍照时,活动存储图像并存储一个txt文件,它记录了手机的gps位置和方向(即加速度计和数字指南针读数) . 活动有效,但我不确定它是否写得正确 . 我是android和java的新手,所以如果有人可以检查它并且会很棒 . 我很担心,因为当我第一次开始开发时,我的开发设备开始变得有趣和过热 . 虽然我不是100%肯定,但它可能与编码错误有关 . 也许与我将所有内容的引用传递给每个类的方式有关,可能不是一个好主意,但我想不出另一种方法来做,感谢任何帮助 .

这是主要的活动代码:

package com.mobimm;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;


import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.Time;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;

public class CameraAct extends Activity {
    private CamCapture mPreview;
    private DrawOnTop mDrawOnTop;
    private OrientationManager mOri;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // Create our Preview view and set it as the content of our activity.
        mOri = new OrientationManager();
        mPreview = new CamCapture(this, mOri);
        mDrawOnTop = new DrawOnTop(this, mPreview, mOri);
        setContentView(mPreview);
        addContentView(mDrawOnTop, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

        mHandler = new Handler();
        mHandler.postDelayed(mUpdateUI, 1000);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mOri.isSupported(this.getApplicationContext())) {
            mOri.startListening(this.getApplicationContext());
        }
        mPreview.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mOri.isSupported(this.getApplicationContext())) {
            mOri.stopListening();
        }
        mPreview.pause();
    }

    private Runnable mUpdateUI = new Runnable() {
           public void run() {
                mDrawOnTop.invalidate();            
                mHandler.postDelayed(mUpdateUI, 1000);
           }
        };
}

// ----------------------------------------------------------------------

class DrawOnTop extends View {
    Paint mPaintWhite;
    String mStatus;
    CamCapture mCam;
    OrientationManager mOri;

    public DrawOnTop(Context context, CamCapture cam, OrientationManager ori) {
        super(context);

        mCam = cam;
        mOri = ori;

        mStatus = "Waiting";

        mPaintWhite = new Paint();
        mPaintWhite.setStyle(Paint.Style.FILL);
        mPaintWhite.setColor(Color.WHITE);
        mPaintWhite.setTextSize(25);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        int canvasHeight = canvas.getHeight();

        // Draw String
        canvas.drawText(Math.round(mOri.getAzimuth())+" "+Math.round(mOri.getPitch())+" "+Math.round(mOri.getRoll()), 10, canvasHeight - 30, mPaintWhite);
        if (mOri.getGPSAcc()  0) {
            canvas.drawText((Math.round((mOri.getLat()*100000))/100000.0)+","+(Math.round((mOri.getLng()*100000))/100000.0)+" "+mOri.getGPSAcc(), 10, canvasHeight - 60, mPaintWhite);
        } else {
            canvas.drawText("Looking For Satillates "+mOri.getGPSAcc(), 10, canvasHeight - 60, mPaintWhite);
        }
        canvas.drawText(mStatus, 10, canvasHeight - 90, mPaintWhite);
    }

    @Override
    public boolean onTouchEvent(final MotionEvent event) {
        mCam.setRecording(true);

        return true;
    }
} 

 // ----------------------------------------------------------------------

class CamCapture extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;
    // byte[] mYUVData;
    // int[] mRGBData;
    Bitmap mBitmap[];
    int mImageWidth, mImageHeight;
    long mLastImgScan;
    boolean mRecording;
    String mFilename;
    String mCSVStore;
    OrientationManager mOri;
    PictureCallback mJpegCallback;
    ShutterCallback mShutterCallback;

    CamCapture(CameraAct context, OrientationManager ori) {
        super((Context) context);

        mOri = ori;
        mRecording = false;
        mCSVStore = "";
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mHolder.setFormat(PixelFormat.TRANSLUCENT); 
        mImageWidth = 0;
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);

           // Preview callback used whenever new viewfinder frame is available
           mCamera.setPreviewCallback(new PreviewCallback() {
              public void onPreviewFrame(byte[] data, Camera camera)
              {
                  if (mImageWidth == 0)
                  {
                      // Initialize the draw-on-top companion
                      Camera.Parameters params = camera.getParameters();
                      mImageWidth = params.getPreviewSize().width;
                      mImageHeight = params.getPreviewSize().height;
                      // mYUVData = new byte[data.length*10];
                      // mRGBData = new int[data.length*10];
                      mLastImgScan = System.currentTimeMillis();
                  }

                  if (mRecording) {
                      mRecording = false;
                      mBitmap = new Bitmap[1];
                      mLastImgScan = System.currentTimeMillis();
                      camera.takePicture(mShutterCallback, null, mJpegCallback);
                      Log.w("CamInfo", "Taking Photo");
                  }
              }
           });

           mShutterCallback = new ShutterCallback() {
               public void onShutter() {
                  mCSVStore = mOri.getString();
                  Log.w("CamInfo", "Getting Cam Data For Photo");
               }
           };

           mJpegCallback = new PictureCallback() {
               public void onPictureTaken(byte[] _data, Camera _camera) {
                  Log.w("CamInfo", "Saving Cam Image For Photo");
                  try {
                      FileOutputStream outimg = new FileOutputStream("/sdcard/fypcamera/"+mFilename+".jpg");
                      outimg.write(_data);
                      outimg.close();
                      //mBitmap[mCounter] = BitmapFactory.decodeByteArray(_data, 0, _data.length);
                      _data = null;
                      outimg = null;

                      File f = new File("/sdcard/cameratesting/"+mFilename+".csv");
                      //File f = new File("/sdcard/"+mFilename+".txt");
                      FileWriter fw = new FileWriter(f);
                      BufferedWriter outtxt = new BufferedWriter(fw);
                      outtxt.write(mCSVStore);
                      outtxt.close();
                      f = null;
                      outtxt = null;
                      mCSVStore = "";
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  mBitmap = null;
                  mCSVStore = "";
                  mCamera.startPreview();
               }
           };


        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
        }
    }


    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        // Because the CameraDevice object is not a shared resource, it's very
        // important to release it when the activity is paused.
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(320, 240);
            parameters.setPreviewFrameRate(10);
            parameters.setSceneMode(Camera.Parameters.SCENE_MODE_LANDSCAPE);
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
            parameters.setJpegQuality(100);
            //parameters.setPictureFormat(PixelFormat.RGB_565);
            //parameters.setPreviewFormat(PixelFormat.RGB_565); // set preview to ImageFormat.RGB_565
            mCamera.setParameters(parameters);
            mCamera.startPreview();
        }
    }

    public void pause() {
        if (mCamera != null) mCamera.stopPreview();
    }

    public void resume() {
        if (mCamera != null) mCamera.startPreview();
    }

    public void setRecording(boolean set) {
        Time timestr = new Time();
        timestr.set(System.currentTimeMillis());
        mFilename = timestr.format2445();
        mRecording = set;
    }

    public boolean getRecording() {
        return (mRecording || mCSVStore != "");
    }
}

这是orientationmanager代码:

package com.mobimm;
import java.util.List;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class OrientationManager {
    private Sensor sensor;
    private SensorManager sensorManager;
    private LocationManager locationManager;
    private double lat;
    private double lng;
    private float gpsacc;
    private float[] mR = null;
    private float[] mI = null;
    private float[] mMag;
    private float[] mGrv;
    private float[] mAng;

    // you could use an OrientationListener array instead
    // if you plans to use more than one listener

    /** indicates whether or not Orientation Sensor is supported */
    private Boolean supported;
    /** indicates whether or not Orientation Sensor is running */
    private boolean running = false;

    public OrientationManager() {
        mMag = new float[3];
        mGrv = new float[3];
        mAng = new float[3];
        mR = new float[16];
        mI = new float[16];
    }
    /**
     * Returns true if the manager is listening to orientation changes
     */
    public boolean isListening() {
        return running;
    }

    /**
     * Returns Ori Matrix
     */
    public float[] getMatrix() {
        return mR;
    }

    /**
     * Returns Magnetic Vector
     */
    public Vec getMagVec() {
        return new Vec(mMag[0], mMag[1], mMag[2]);
    }
    /**
     * Returns Gravity Vector
     */
    public Vec getGravVec() {
        return new Vec(mGrv[0], mGrv[1], mGrv[2]);
    }

    /**
     * Returns azimuth
     */
    public float getAzimuth() {
        return mAng[0];
    }
    /**
     * Returns azimuth
     */
    public float getPitch() {
        return mAng[1];
    }
    /**
     * Returns azimuth
     */
    public float getRoll() {
        return mAng[2];
    }

    /**
     * Returns lat
     */
    public float getLat() {
        return (float) lat;
    }

    /**
     * Returns lng
     */
    public float getLng() {
        return (float) lng;
    }

    /**
     * Returns lng
     */
    public float getGPSAcc() {
        return (float) gpsacc;
    }

    public String getString() {
        // output format = time,lat,lng,GPS acc, Ori Azimuth, Ori Pitch, Ori Roll, Acc x, Acc y, Acc z, Mag x, Mag y, Mag z
        String rtn = System.currentTimeMillis()+"\n";
        rtn += "GPS,";
        rtn += lat+",";
        rtn += lng+",";
        rtn += gpsacc+"\n";
        rtn += "Angles,";
        rtn += mAng[0]+",";
        rtn += mAng[1]+",";
        rtn += mAng[2]+"\n";
        rtn += "Gravtiy,";
        rtn += mGrv[0]+",";
        rtn += mGrv[1]+",";
        rtn += mGrv[2]+",";
        rtn += "Magnet,";
        rtn += mMag[0]+",";
        rtn += mMag[1]+",";
        rtn += mMag[2]+"\n";
        rtn += "Matrix,";
        rtn += mR[0]+",";
        rtn += mR[1]+",";
        rtn += mR[2]+",";
        rtn += mR[3]+"\n";
        rtn += " ,";
        rtn += mR[4]+",";
        rtn += mR[5]+",";
        rtn += mR[6]+",";
        rtn += mR[7]+"\n";
        rtn += " ,";
        rtn += mR[8]+",";
        rtn += mR[9]+",";
        rtn += mR[10]+",";
        rtn += mR[11]+"\n";
        rtn += " ,";
        rtn += mR[12]+",";
        rtn += mR[13]+",";
        rtn += mR[14]+",";
        rtn += mR[15]+"\n";
        return rtn;
    }
    /**
     * Unregisters listeners
     */
    public void stopListening() {
        running = false;
        try {
            if (sensorManager != null && sensorEventListener != null) {
                sensorManager.unregisterListener(sensorEventListener);
            }
            if (locationManager != null && locListener != null) {
                locationManager.removeUpdates(locListener);
            }
        } catch (Exception e) {}
    }

    /**
     * Returns true if at least one Orientation sensor is available
     */
    public boolean isSupported(Context context) {
        if (supported == null) {
            if (context != null) {
                sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
                //List sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
                //sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
                //supported = new Boolean(sensors.size() > 0);
                List sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
                supported = new Boolean(sensors.size() > 0);
                sensors = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
                supported = (supported && new Boolean(sensors.size() > 0));
            } else {
                supported = Boolean.FALSE;
            }
        }
        return supported;
    }

    /**
     * Registers a listener and start listening
     */
    public void startListening(Context context) {
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        /*
        List sensors = sensorManager.getSensorList(
                Sensor.TYPE_ORIENTATION);
        if (sensors.size() > 0) {
            sensor = sensors.get(0);
            running = sensorManager.registerListener(
                    sensorEventListener, sensor, 
                    SensorManager.SENSOR_DELAY_GAME);
        }
        */
        List sensors = sensorManager.getSensorList(
                Sensor.TYPE_ACCELEROMETER);
        if (sensors.size() > 0) {
            sensor = sensors.get(0);
            running = sensorManager.registerListener(
                    sensorEventListener, sensor, 
                    SensorManager.SENSOR_DELAY_GAME);
        }
        sensors = sensorManager.getSensorList(
                Sensor.TYPE_MAGNETIC_FIELD);
        if (sensors.size() > 0) {
            sensor = sensors.get(0);
            running = sensorManager.registerListener(
                    sensorEventListener, sensor, 
                    SensorManager.SENSOR_DELAY_GAME);
        }
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        try {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000L, 2f, locListener);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * The listener that listen to events from the orientation listener
     */
    private SensorEventListener sensorEventListener = 
        new SensorEventListener() {

        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

        public void onSensorChanged(SensorEvent event) {
            /*
            if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
                azimuth = event.values[0];     // azimuth
                pitch = event.values[1];     // pitch
                roll = event.values[2];        // roll
             }
            */
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                mGrv = event.values;
            }
            if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                mMag = event.values;
            }
            if (SensorManager.getRotationMatrix(mR, mI, mGrv, mMag)) {
                SensorManager.getOrientation(mR, mAng);
                mAng[0] = (float) Math.toDegrees(mAng[0]);
                mAng[1] = (float) Math.toDegrees(mAng[1]);
                mAng[2] = (float) Math.toDegrees(mAng[2]);
                float[] tmp = new float[16]; 
                for (int i = 0; i

再次感谢您的帮助