Correct combination of sensor management and camera on android
I have written an android activity to act as a simple camera but when I photo is taken the activity stores the image and stores a txt file along side, which records the gps location and orientation of the phone (ie the accelerometer and digital compass readings). The activity works but I'm unsure it has been written correctly. I'm abit of a novice on android and java so if some one could check over it and would be great. I'm worried because when I first started developing this my development device started to get all funny and overheating and things. Although I'm not 100% sure, it could have something to do with this being coded wrong. Maybe to do with the way I pass references to everything to every class, probably not a good idea but I can't think of another way to do it, Thanks for any help.
This is the main activity code:
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 != "");
}
}
And this is the orientationmanager code:
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
Again thanks for any help
链接地址: http://www.djcxy.com/p/32024.html上一篇: 基于文本的冒险游戏。