正如我所看到的,在第三種方法中,您試圖找到兩個矢量(重力矢量和加速度矢量)之間角度的cos。這個想法是,如果角度接近於180度,那麼如果角度接近0度,則表示您有向下移動。當角度從-90到90度時,餘弦函數具有正值。所以當你的cosineVal
值是正值時,這意味着手機正在下降,即使餘弦值接近1的運動是直線下降。所以反過來也是如此。當餘弦爲負值時(從90度到270度),你有運動。
可能你可以從Sensor.TYPE_ACCELEROMETER
從https://developer.android.com/reference/android/hardware/SensorEvent.html#values載荷那裏你有重力矢量和加速度向量。
我在下面做了一段代碼,你可以試試。
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private float[] gravity = new float[3];
private float[] linear_acceleration = new float[3];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onSensorChanged(SensorEvent event) {
// alpha is calculated as t/(t + dT)
// with t, the low-pass filter's time-constant
// and dT, the event delivery rate
final float alpha = 0.8f;
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];
float scalarProduct = gravity[0] * linear_acceleration[0] +
gravity[1] * linear_acceleration[1] +
gravity[2] * linear_acceleration[2];
float gravityVectorLength = (float) Math.sqrt(gravity[0] * gravity[0] +
gravity[1] * gravity[1] + gravity[2] * gravity[2]);
float lianearAccVectorLength = (float) Math.sqrt(linear_acceleration[0] * linear_acceleration[0] +
linear_acceleration[1] * linear_acceleration[1] + linear_acceleration[2] * linear_acceleration[2]);
float cosVectorAngle = scalarProduct/(gravityVectorLength * lianearAccVectorLength);
TextView tv = (TextView) findViewById(R.id.tv);
if (lianearAccVectorLength > 2) {//increase to detect only bigger accelerations, decrease to make detection more sensitive but noisy
if (cosVectorAngle > 0.5) {
tv.setText("Down");
} else if (cosVectorAngle < -0.5) {
tv.setText("Up");
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}