2013-05-15 3 views
8

Я использую демонстрационный ТАЙМЕР с вибрацией (при определенном условии), Когда я нажимаю кнопку запуска, мой таймер начинает работать .. и когда я останавливаю его с помощью кнопки остановки, он просто останавливается.Обнаружение движения с использованием Accelerometer в Android

Теперь мне нужно интегрировать функциональность, когда человек переводит устройство (пока таймер работает), он должен сбросить таймер. Он работает очень хорошо, но функциональность акселерометра работает не совсем точно. Для сброса таймера требуется быстрый рывок.

Предложите мне хорошее решение для того же.

Вот мой код

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

} 

ответ

6

Я думаю, что следующим этапом в разработке вашего приложения является просмотр значений ускорения, которые производятся в электронной таблице. Я использую Excel для этого, но любой инструмент, который может создавать графики, будет делать. Поэтому изменить 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); 

} 

, а затем вы можете захватить CURRENTTIME, mAccelCurrent и mAccel в механизм Android протоколирования. Кроме того, создайте свой собственный текстовый файл, напишите там значения и откройте файл в инструменте, который может создавать графики. Из графиков вы можете решить, какие значения использовать для вашего триггера.

+0

Мой простой вопрос - как проверить данные наклона (когда устройство наклонено), и я хочу выполнить набор кода на нем. у вас есть какое-либо решение в отношении вышеуказанного кода. –

+0

@stochastically. Мой вопрос такой же, как и выше –

+0

Я думал, что вы хотите использовать данные акселерометра для обнаружения движения. Для этого вам нужно понять данные, поэтому необходимо занести их в журнал и посмотреть на него. Если вы просто хотите проверить, когда устройство наклонено, это намного проще. Например, см. Мой answser [ссылка] (http://stackoverflow.com/questions/16571798/android-device-angle-on-vertical-axis-while-device-stays-still/16572641#16572641). Угол наклона, вероятно, то, что вы ищете. – Stochastically

2

Два предложения, и одна мысль:

  1. Для последовательного поведения, вы должны смотреть на длину event.values, то есть Math.sqrt(x*x+y*y+z*z), а не отдельные значения. Математически это Math.sqrt(x*x+y*y+z*z), что не зависит от вашей системы координат, то есть как устройство ориентировано относительно земли и т. Д., Тогда как отдельные числа x, y, z не являются.
  2. Ваше текущее приложение ищет изменения в ускорении. Вместо этого, я думаю, вам стоит просто искать большое ускорение, то есть большие значения Math.sqrt(x*x+y*y+z*z).
  3. Я недавно написал this answer об использовании акселерометров для шагомера, и я думаю, вам может показаться интересным.

+0

Вы предоставили очень хороший ответ, но я не могу понять, что мне делать, чтобы проверить движение устройства.? Где я должен изменить свой код .. так что, если человек немного изменит положение устройства, я должен его получить. –

+0

Мои комментарии 1 и 2 относятся к вашей реализации 'onSensorChanged (событие SensorEvent)'. Ваши первые 3 строки в порядке, где вы устанавливаете x, y и z, но тогда вам нужно (1) получить 'len = Math.sqrt (x * x + y * y + z * z)'. и (2) определить, является ли len намного больше, чем обычно. – Stochastically

+2

Я не думаю, что редактирование вопроса, как это хорошая идея, потому что мой ответ и наш разговор теперь имеют меньший смысл для других. Кроме того, ваше редактирование является неполным, поскольку переменные, такие как mAccel, не объявляются нигде. Вы должны начать новый вопрос, если у вас все еще есть проблемы. Тем не менее, похоже, вы пытаетесь сделать «mAccel» сглаженное значение «mAccelCurrent» довольно странным образом. Вместо этого я предлагаю «mAccel = mAccel * 0.9f + mAccelCurrent * 0.1f'. Помимо этого, я думаю, что вы должны записывать файлы mAccel и mAccelCurrent в файл, анализировать результаты и решать, что делать с этим. – Stochastically

Смежные вопросы