Detectar movimiento con precisión usando acelerómetro en Android

Estoy implementando un TIMER de demostración, con Vibración (en una condición particular), Cuando presione iniciar mi temporizador comienza a funcionar .. y cuando lo detengo con el botón de parada, simplemente se detiene.

Ahora tengo que integrar una funcionalidad, cuando la persona cambia el dispositivo (mientras que el temporizador está funcionando) , debe reajustar el contador de tiempo. Está funcionando bastante bien, pero la funcionalidad del acelerómetro no está funcionando absolutamente precisa. Necesita un tirón rápido para restablecer el temporizador.

Sugerirme una buena solución para el mismo.

Aquí está mi código

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); } 

}

Actividad del temporizador

 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(); }; } 

Creo que la siguiente etapa en el desarrollo de su aplicación es mirar los valores de aceleración que se producen en una hoja de cálculo. Utilizo Excel para esto, pero cualquier herramienta que puede producir gráficos hará. Así que alter onSensorChanged() a algo como

 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); } 

Y luego puede capturar el currentTime, mAccelCurrent y mAccel en el mecanismo de registro de Android. Como alternativa, cree su propio archivo de texto, escriba los valores allí y abra el archivo en una herramienta que puede producir gráficos. A partir de los gráficos, puede decidir qué valores usar para su desencadenador.

Dos sugerencias, y un pensamiento:

  1. Para un comportamiento consistente, debe buscar la longitud del vector event.values, es decir, Math.sqrt(x*x+y*y+z*z) , en lugar de los valores individuales. Matemáticamente, es Math.sqrt(x*x+y*y+z*z) que es independiente de su sistema de coordenadas, es decir, cómo el dispositivo está orientado en relación con el suelo, etc., mientras que los números individuales x, yz z aren T
  2. Su aplicación actual busca cambios en la aceleración. En su lugar, creo que sólo debe buscar aceleración alta, es decir, grandes valores de Math.sqrt(x*x+y*y+z*z) .
  3. Recientemente escribí esta respuesta sobre el uso de acelerómetros para un podómetro, y creo que podría resultar interesante.
  • Gyro Sensor drift y Estimación de ángulo correcto
  • Evento TYPE_MAGNETIC_FIELD que no dispara en mi Galaxy Nexus ICS 4.0.2
  • Perfiles de Acelerómetro Android
  • Unity3D Android acelerómetro y giroscopio controles
  • Cómo calcular la velocidad de carrera utilizando sensor acelerómetro en android
  • Cómo eliminar Factor de gravedad de las lecturas del acelerómetro en el acelerómetro Android de 3 ejes
  • Componentes de la gravedad del acelerómetro
  • ¿Cuál es la diferencia entre sensores de "gravedad" y "aceleración" en Android?
  • Android acelerómetro, uso de sensores y consumo de energía
  • ¿Cómo / Debo implementar un filtro de Kalman para obtener datos precisos de Acelerómetro?
  • ¿Cómo puedo simular el acelerómetro en el emulador de Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.