私は単純なカメラとして機能する Android アクティビティを作成しましたが、写真を撮ると、アクティビティは画像を保存し、携帯電話の gps 位置と方向 (つまり、加速度計とデジタル コンパスの読み取り値) を記録する txt ファイルを横に保存します。 . アクティビティは機能しますが、正しく記述されているかどうかはわかりません。私は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 != "");
}
}
そして、これはオリエンテーションマネージャーのコードです:
パッケージ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 をインポートします。 public class OrientationManager { プライベート センサー センサー; プライベート SensorManager sensorManager; プライベート LocationManager locationManager; プライベートダブルラット; プライベートダブルlng; プライベート フロート gpsacc; プライベート フロート[] mR = null; プライベート フロート[] mI = null; プライベート フロート[] mMag; プライベートフロート[] mGrv; プライベートフロート[] mAng; // 代わりに OrientationListener 配列を使用できます // 複数のリスナーを使用する場合 /** 方向センサーがサポートされているかどうかを示します */ private ブール値がサポートされています。 /** 方向センサーが実行されているかどうかを示します */ プライベート ブール値の実行中 = false; public OrientationManager() { mMag = 新しい float[3]; mGrv = 新しい float[3]; mAng = 新しい float[3]; mR = 新しい float[16]; mI = 新しい float[16]; } /** * マネージャーが向きの変更をリッスンしている場合は true を返します */ public boolean isListening() { ランニングを返します。 } /** * Ori マトリックスを返します */ public float[] getMatrix() { mR を返します。 } /** * 磁気ベクトルを返します */ public Vec getMagVec() { 新しい Vec(mMag[0]、mMag[1]、mMag[2]) を返します。 } /** * 重力ベクトルを返します */ public Vec getGravVec() { return new Vec(mGrv[0], mGrv[1], mGrv[2]); } /** * 方位角を返します */ public float getAzimuth() { mAng[0] を返します。 } /** * 方位角を返します */ public float getPitch() { mAng[1] を返します。 } /** * 方位角を返します */ public float getRoll() { mAng[2] を返します。 } /** *緯度を返します */ public float getLat() { リターン(フロート)緯度; } /** * lng を返します */ public float getLng() { return (float) lng; } /** * lng を返します */ public float 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 += 「GPS」; rtn += lat+","; 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 を返します。 } /** * リスナーの登録を解除します */ public void stopListening() { 実行中 = false; 試す { if (sensorManager != null && sensorEventListener != null) { sensorManager.unregisterListener(sensorEventListener); } if (locationManager != null && locListener != null) { locationManager.removeUpdates(locListener); } } キャッチ (例外 e) {} } /** * 少なくとも 1 つの方向センサーが利用可能な場合は true を返します */ public boolean isSupported(Context context) { if (サポート == null) { if (コンテキスト != null) { sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); //センサーのリスト = sensorManager.getSensorList(Sensor.TYPE_ALL); //sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION); //supported = new Boolean(sensors.size() > 0); センサーの一覧表示 = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); サポートされている = 新しいブール値 (センサー.サイズ () > 0); センサー = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD); サポートされている = (サポートされている && new Boolean(sensors.size() > 0)); } そうしないと { サポートされている = Boolean.FALSE; } } 返品対応; } /** * リスナーを登録してリスニングを開始 */ public void startListening(Context context) { sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); /* センサーの一覧表示 = sensorManager.getSensorList( Sensor.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( Sensor.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(センサー センサー、int 精度) {} public void 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]); float[] tmp = 新しい float[16]; for (int i = 0; i
もう一度助けてくれてありがとう