2

我编写了一个 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代码:

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

公共类 OrientationManager {
    私人传感器传感器;
    私有传感器管理器传感器管理器;
    私人位置管理器位置管理器;
    私人双纬度;
    私人双液化天然气;
    私人浮动 gpsacc;
    私人浮动[] mR = null;
    私人浮动[] mi = null;
    私人浮动[] mMag;
    私人浮动[] mGrv;
    私人浮动[] mAng;

    // 你可以使用 OrientationListener 数组代替
    // 如果你打算使用多个监听器

    /** 表示是否支持方向传感器 */
    支持私有布尔值;
    /** 表示方向传感器是否正在运行 */
    私人布尔运行=假;

    公共方向管理器(){
        mMag = 新浮点数[3];
        mGrv = 新浮点数[3];
        mAng = 新浮点数[3];
        mR = 新浮点数[16];
        mi = 新浮点数[16];
    }
    /**
     * 如果经理正在监听方向变化,则返回 true
     */
    公共布尔 isListening() {
        返回运行;
    }

    /**
     * 返回 Ori 矩阵
     */
    公共浮动[] getMatrix() {
        返回mR;
    }

    /**
     * 返回磁矢量
     */
    公共 Vec getMagVec() {
        返回新的 Vec(mMag[0], mMag[1], mMag[2]);
    }
    /**
     * 返回重力向量
     */
    公共 Vec getGravVec() {
        返回新的 Vec(mGrv[0], mGrv[1], mGrv[2]);
    }

    /**
     * 返回方位角
     */
    公共浮动 getAzimuth() {
        返回 mAng[0];
    }
    /**
     * 返回方位角
     */
    公共浮动 getPitch() {
        返回 mAng[1];
    }
    /**
     * 返回方位角
     */
    公共浮动 getRoll() {
        返回 mAng[2];
    }

    /**
     * 返回纬度
     */
    公共浮动 getLat() {
        返回(浮动)纬度;
    }

    /**
     * 返回 lng
     */
    公共浮动getLng(){
        返回(浮动)液化天然气;
    }

    /**
     * 返回 lng
     */
    公共浮动 getGPSAcc() {
        返回(浮动)gpsacc;
    }

    公共字符串 getString() {
        // 输出格式 = time,lat,lng,GPS acc, Ori Azimuth, Ori Pitch, Ori Roll, Acc x, Acc y, Acc z, Mag x, Mag y, Mag z
        字符串 rtn = System.currentTimeMillis()+"\n";
        rtn +=“全球定位系统”,;
        rtn += 纬度+",";
        rtn += lng+",";
        rtn += gpsacc+"\n";
        rtn += "角度";
        rtn += mAng[0]+",";
        rtn += mAng[1]+",";
        rtn += mAng[2]+"\n";
        rtn += "重力";
        rtn += mGrv[0]+",";
        rtn += mGrv[1]+",";
        rtn += mGrv[2]+",";
        rtn += "磁铁";
        rtn += mMag[0]+",";
        rtn += mMag[1]+",";
        rtn += mMag[2]+"\n";
        rtn += "矩阵";
        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";
        返回rtn;
    }
    /**
     * 注销监听器
     */
    公共无效停止监听(){
        运行=假;
        尝试 {
            if (sensorManager != null && sensorEventListener != null) {
                sensorManager.unregisterListener(sensorEventListener);
            }
            if (locationManager != null && locListener != null) {
                locationManager.removeUpdates(locListener);
            }
        } 捕捉(异常 e){}
    }

    /**
     * 如果至少有一个方向传感器可用,则返回 true
     */
    公共布尔isSupported(上下文上下文){
        如果(支持 == null){
            如果(上下文!= null){
                sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
                //列出传感器 = sensorManager.getSensorList(Sensor.TYPE_ALL);
                //sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
                //支持 = new Boolean(sensors.size() > 0);
                列出传感器 = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
                支持 = new Boolean(sensors.size() > 0);
                传感器 = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
                支持 = (支持 && new Boolean(sensors.size() > 0));
            } 别的 {
                支持 = Boolean.FALSE;
            }
        }
        支持退货;
    }

    /**
     * 注册一个监听器并开始监听
     */
    public void startListening(上下文上下文){
        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        /*
        列出传感器 = sensorManager.getSensorList(
                传感器.TYPE_ORIENTATION);
        如果(传感器大小()> 0){
            传感器 = 传感器.get(0);
            运行 = sensorManager.registerListener(
                    传感器事件监听器,传感器,
                    SensorManager.SENSOR_DELAY_GAME);
        }
        */
        列出传感器 = sensorManager.getSensorList(
                Sensor.TYPE_ACCELEROMETER);
        如果(传感器大小()> 0){
            传感器 = 传感器.get(0);
            运行 = sensorManager.registerListener(
                    传感器事件监听器,传感器,
                    SensorManager.SENSOR_DELAY_GAME);
        }
        传感器 = sensorManager.getSensorList(
                传感器.TYPE_MAGNETIC_FIELD);
        如果(传感器大小()> 0){
            传感器 = 传感器.get(0);
            运行 = sensorManager.registerListener(
                    传感器事件监听器,传感器,
                    SensorManager.SENSOR_DELAY_GAME);
        }
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        尝试 {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000L, 2f, locListener);
        } 捕捉(异常 e){
            e.printStackTrace();
        }
    }

    /**
     * 从方向监听器监听事件的监听器
     */
    私人 SensorEventListener sensorEventListener =
        新的 SensorEventListener() {

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

        公共无效 onSensorChanged(SensorEvent 事件){
            /*
            if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
                方位角 = event.values[0]; // 方位角
                音调 = event.values[1]; // 沥青
                滚动 = event.values[2]; // 卷
             }
            */
            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]);
                浮动[] tmp = 新浮动[16];
                对于 (int i = 0; 我

再次感谢您的帮助

4

0 回答 0