在Android中使用Accelerometer准确检测移动

我正在执行演示定时器,振动(在特定的条件下),当我按开始我的定时器开始运行..当我停止它使用停止button,它只是停止。

现在我必须集成一个function,当人员移动设备时(定时器正在运行) ,它应该重置定时器。 它工作的很好,但是加速度计function并不完全正确。 它需要一个快速突然的重置计时器。

build议我一个很好的解决scheme。

这是我的代码

public class SensorAccelerometer implements SensorEventListener { private Context context; private SensorManager sensorManager; private Sensor accelerometer; private TextView timelabel; private Handler mHandler; Runnable run; private float mLastX, mLastY, mLastZ; private final float NOISE = (float) 3.0; public SensorAccelerometer(Context context) { } public SensorAccelerometer(Context context,TextView timelabel, Handler mHandler2, Runnable mUpdateTimeTask) { // TODO Auto-generated constructor stub this.context = context; this.timelabel = timelabel; this.mHandler = mHandler2; this.run = mUpdateTimeTask; initialiseSensor(); } public void initialiseSensor(){ sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ALL); sensorManager.registerListener(this, accelerometer,SensorManager.SENSOR_DELAY_NORMAL); } public void unregisterSensor(){ sensorManager.unregisterListener(this); Toast.makeText(context, "Sensor Stopped..", Toast.LENGTH_SHORT).show(); } public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; mAccelLast=mAccelCurrent; mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z); float delta = mAccelCurrent - mAccelLast; mAccel = mAccel * 0.9f + delta; if(mAccel>0.5){ TimerActivity.mStartTime = SystemClock.uptimeMillis(); mHandler.removeCallbacks(run); mHandler.postDelayed(run, 100); } 

}

计时器活动

 public class TimerActivity extends Activity { public static long mStartTime = 0L; private TextView mTimerLabel; private Handler mHandler = new Handler(); String timerStop1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTimerLabel = (TextView) findViewById(R.id.textTimer); Button timerStartButton = (Button) findViewById(R.id.btnTimer); timerStartButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view){ if(mStartTime == 0L){ mStartTime = SystemClock.uptimeMillis(); mHandler.removeCallbacks(mUpdateTimeTask); mHandler.postDelayed(mUpdateTimeTask, 100); //activating the sensor and the acclerometer SensorAccelerometer acc = new SensorAccelerometer(view.getContext(), mTimerLabel,mHandler,mUpdateTimeTask); } } }); Button timerStopButton = (Button) findViewById(R.id.btnTimerStop); timerStopButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view){ mHandler.removeCallbacks(mUpdateTimeTask); mTimerLabel.setText(timerStop1); mStartTime = 0L; SensorAccelerometer scc = new SensorAccelerometer(view.getContext(),mTimerLabel,mHandler,mUpdateTimeTask); scc.unregisterSensor(); } }); } private Runnable mUpdateTimeTask = new Runnable(){ public void run() { final long start = mStartTime; long millis = SystemClock.uptimeMillis()- start; int seconds = (int) (millis / 1000); int minutes = seconds / 60; seconds = seconds % 60; mTimerLabel.setText("" + minutes + ":" + String.format("%02d", seconds)); timerStop1 = minutes + ":" + String.format("%02d", seconds); mHandler.postDelayed(this, 200); } }; protected void onPause() { super.onPause(); SensorAccelerometer scc = new SensorAccelerometer(this,mTimerLabel,mHandler,mUpdateTimeTask); scc.unregisterSensor(); }; } 

Solutions Collecting From Web of "在Android中使用Accelerometer准确检测移动"

我认为您的应用程序开发的下一个阶段是查看电子表格中生成的加速度值。 我为此使用Excel,但任何可以生成graphics的工具都可以。 所以改变onSensorChanged()的东西

 public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; float mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z); float mAccel = mAccel * 0.9f + mAccelCurrent * 0.1f; Log.d("onSensorChanged",System.currentTimeMillis()+","+mAccelCurrent +","+mAccel); } 

然后你就可以将当前时间,mAccelCurrent和mAccel捕获到Android日志logging机制中。 或者,创build自己的文本文件,在其中写入值,然后在可生成graphics的工具中打开该文件。 从图表中,您可以决定触发器使用的值。

两个build议,一个想法:

  1. 对于一致的行为,您应该查看event.values向量的长度,即Math.sqrt(x*x+y*y+z*z) ,而不是单个值。 在math上,它是独立于坐标系统的Math.sqrt(x*x+y*y+z*z) ,即设备如何相对于地面定向等,而单个数字x,y,z aren “T。
  2. 您当前的应用程序查找加速度的变化。 相反,我认为你应该只考虑高加速度,即Math.sqrt(x*x+y*y+z*z)较大值。
  3. 我最近写了这个关于使用加速度计的计步器的答案 ,我想你可能会觉得它很有趣。