2011-06-11 74 views
5

我試着用加速度計來檢測搖動事件。 我發現當我對手機進行連續搖晃時,加速度的差值 非常穩定。 但是當我旋轉手機時,這個值總是會有很大的改變(通常這個值比「沒有旋轉時晃動」更大)。 我想關注搖動事件,而不是旋轉事件。有沒有辦法解決 的問題?是否有穩定的方法來檢測搖動事件?

,這裏是我的shaing檢測

public void onSensorChanged(SensorEvent event) 
    { 
     if (event.sensor.getType() == SensorManager.SENSOR_ACCELEROMETER) 
     { 
      nowTime = System.currentTimeMillis(); 

      float x = event.values[SensorManager.DATA_X]; 
      float y = event.values[SensorManager.DATA_Y]; 
      float z = event.values[SensorManager.DATA_Z]; 
      nowAcc = Math.sqrt(x*x+y*y+z*z); 
      accDiff = Math.abs(nowAcc - preAcc); 
      timeDiff = (nowTime - preTime); 
         // try to get the sum of 10 samplings of accDiff 
      tempAccDiff10 = tempAccDiff9; 
      tempAccDiff9 = tempAccDiff8; 
      tempAccDiff8 = tempAccDiff7; 
      tempAccDiff7 = tempAccDiff6; 
      tempAccDiff6 = tempAccDiff5; 
      tempAccDiff5 = tempAccDiff4; 
      tempAccDiff4 = tempAccDiff3; 
      tempAccDiff3 = tempAccDiff2; 
      tempAccDiff2 = tempAccDiff1; 
      tempAccDiff1 = accDiff; 
      sumAcc = tempAccDiff10+tempAccDiff9+tempAccDiff8+tempAccDiff7+tempAccDiff6+ 
        tempAccDiff5+tempAccDiff4+tempAccDiff3+tempAccDiff2+tempAccDiff1; 
      Log.i("SSSS",String.valueOf(sumAcc)); 
         //when I give the phone a big & continuous "shake", it returns 
         //a value about 30~40, but when I give the phone a small 
         //"rotation", it returns a value of 80~120 
      preAcc = nowAcc; 
      preTime = nowTime; 
      if (sumAcc>100) 
      { 
       SM.unregisterListener(sensorListener, sensor); 
      } 

      //123 
     } 


    }//end of onSensorChanged(); 

是有可能忽略使用加速度計旋轉事件代碼? 或者我應該嘗試獲取方向更改並對sumAcc執行一些計算 ?

回答

3

你應該使用一個過濾器來消除重力的影響,有一些tutorial on the docs to do so。我做了類似的事情,在我的情況下,我也在嘗試檢測其他動作,所以你的任務似乎更簡單一些。我可以在星期一發布代碼(如果我記得的話)。

祝你好運!


我編輯的答案補充你可以使用一個Sensor TYPE_LINEAR_ACCELERATION,如果你使用的是Android 2.3或更高版本。這是一種正常的加速度傳感器,它可以放棄重力的影響,因爲您不需要檢測搖動事件。

問候


編輯13/06 - >我答應後我的代碼來檢測晃動,而是,我認爲這是一個更好的主意,張貼this link,這給在代碼樣件各種各樣的反應。我的代碼與那裏發佈的代碼非常相似。

祝你好運!

+0

感謝您的諮詢!我期待的代碼。 我希望我能很快解決這個問題! – Jim31837 2011-06-11 16:32:29

+0

我試圖改變α(高通濾波器常數),但仍然小的旋轉事件導致比大抖動更大的值。其實我使用的是android 2.2 ....我會嘗試線性加速度計,如果我有機會使用2.3設備 – Jim31837 2011-06-11 17:48:55

0

但從代碼來看,你需要實現SensorListener:

public class ShakeActivity extends Activity implements SensorListener 

您將需要獲取的SensorManager:

sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 

並註冊該傳感器與期望的標誌:

ensorMgr.registerListener(this, 
SensorManager.SENSOR_ACCELEROMETER, 
SensorManager.SENSOR_DELAY_GAME); 

在您的onSensorChange()方法中,您可以確定它是否動搖:

private static final int SHAKE_THRESHOLD = 800; 

還有一些其他的方法也一樣,以檢測搖運動:

public void onSensorChanged(int sensor, float[] values) { 
    if (sensor == SensorManager.SENSOR_ACCELEROMETER) { 
    long curTime = System.currentTimeMillis(); 
    // only allow one update every 100ms. 
    if ((curTime - lastUpdate) > 100) { 
     long diffTime = (curTime - lastUpdate); 
     lastUpdate = curTime; 

     x = values[SensorManager.DATA_X]; 
     y = values[SensorManager.DATA_Y]; 
     z = values[SensorManager.DATA_Z]; 

     float speed = Math.abs(x+y+z – last_x – last_y – last_z)/diffTime * 10000; 

     if (speed > SHAKE_THRESHOLD) { 
     Log.d("sensor", "shake detected w/ speed: " + speed); 
     Toast.makeText(this, "shake detected w/ speed: " + speed, Toast.LENGTH_SHORT).show(); 
     } 
     last_x = x; 
     last_y = y; 
     last_z = z; 
    } 
    } 
} 

抖動閾值作爲被定義。看看這個link.(如果那個鏈接不起作用或鏈接已經死了,look at this web archive。)。

謝謝。

相關問題