As I see it, in the 3rd method you trying to find the cos of angle between two vectors (gravity vector and acceleration vector). And the idea is if the angle is close to 180 degrees you have up movement, if angle is close to 0 degrees you have down movement. Cosine is function that has positive value when angle is from -90 to 90 degrees. So when your cosineVal
value is positive it means phone is going down and even if cosineVal closer to 1 movement is straight down. So it is true vice versa. When cosine is negative ( from 90 degrees to 270) you have up movement.
Probably you can get vectors from Sensor.TYPE_ACCELEROMETER
from https://developer.android.com/reference/android/hardware/SensorEvent.html#values there you have gravity vector and acceleration vector.
I made a code snippet below you can try.
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) {
}
}