2 added 141 characters in body edited Apr 12 '14 at 8:15 async 71377 silver badges2222 bronze badges OK, I managed to sort this out and it was a bit stupid. Yes, the low-pass filter DOES solve the problem. Actually here's my code (note I'm doing it in a different method, but just copy and paste the contents in onSensorChanged(SensorEvent) if you wish: private static final float alpha = 0.65f; private static final float SENSITIVITY = 1f/128; private boolean firstTime = true; @Override public void handleSensorEvent(SensorEvent event) { if(firstTime) { vals[0] = event.values[0]; vals[1] = event.values[1]; vals[2] = event.values[2]; } vals[0] = vals[0] + alpha * (event.values[0] - vals[0]); vals[1] = vals[1] + alpha * (event.values[1] - vals[1]); vals[2] = vals[2] + alpha * (event.values[2] - vals[2]); character.setX( character.getX() - vals[0] * SENSITIVITY ); }  You can calibrate alpha and SENSITIVITY according to your needs. Now this is why this code was producing very choppy movement initially: in my activity's onResume() I was registering my listener using SensorEvent.SENSOR_DELAY_NORMAL. That is wrong. What you have to do is register it with SensorEvent.SENSOR_DELAY_GAME. I think the reason behind this is obvious. So in your activity's onResume(): sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);  where accelerometer is declared as (in onCreate()): accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  OK, I managed to sort this out and it was a bit stupid. Yes, the low-pass filter DOES solve the problem. Actually here's my code (note I'm doing it in a different method, but just copy and paste the contents in onSensorChanged(SensorEvent) if you wish: private static final float alpha = 0.65f; private static final float SENSITIVITY = 1f/128; private boolean firstTime = true; @Override public void handleSensorEvent(SensorEvent event) { if(firstTime) { vals[0] = event.values[0]; vals[1] = event.values[1]; vals[2] = event.values[2]; } vals[0] = vals[0] + alpha * (event.values[0] - vals[0]); vals[1] = vals[1] + alpha * (event.values[1] - vals[1]); vals[2] = vals[2] + alpha * (event.values[2] - vals[2]); character.setX( character.getX() - vals[0] * SENSITIVITY ); }  You can calibrate alpha and SENSITIVITY according to your needs. Now this is why this code was producing very choppy movement initially: in my activity's onResume() I was registering my listener using SensorEvent.SENSOR_DELAY_NORMAL. That is wrong. What you have to do is register it with SensorEvent.SENSOR_DELAY_GAME. I think the reason behind this is obvious. So in your activity's onResume(): sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);  OK, I managed to sort this out and it was a bit stupid. Yes, the low-pass filter DOES solve the problem. Actually here's my code (note I'm doing it in a different method, but just copy and paste the contents in onSensorChanged(SensorEvent) if you wish: private static final float alpha = 0.65f; private static final float SENSITIVITY = 1f/128; private boolean firstTime = true; @Override public void handleSensorEvent(SensorEvent event) { if(firstTime) { vals[0] = event.values[0]; vals[1] = event.values[1]; vals[2] = event.values[2]; } vals[0] = vals[0] + alpha * (event.values[0] - vals[0]); vals[1] = vals[1] + alpha * (event.values[1] - vals[1]); vals[2] = vals[2] + alpha * (event.values[2] - vals[2]); character.setX( character.getX() - vals[0] * SENSITIVITY ); }  You can calibrate alpha and SENSITIVITY according to your needs. Now this is why this code was producing very choppy movement initially: in my activity's onResume() I was registering my listener using SensorEvent.SENSOR_DELAY_NORMAL. That is wrong. What you have to do is register it with SensorEvent.SENSOR_DELAY_GAME. I think the reason behind this is obvious. So in your activity's onResume(): sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);  where accelerometer is declared as (in onCreate()): accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);  1 answered Apr 12 '14 at 7:29 async 71377 silver badges2222 bronze badges OK, I managed to sort this out and it was a bit stupid. Yes, the low-pass filter DOES solve the problem. Actually here's my code (note I'm doing it in a different method, but just copy and paste the contents in onSensorChanged(SensorEvent) if you wish: private static final float alpha = 0.65f; private static final float SENSITIVITY = 1f/128; private boolean firstTime = true; @Override public void handleSensorEvent(SensorEvent event) { if(firstTime) { vals[0] = event.values[0]; vals[1] = event.values[1]; vals[2] = event.values[2]; } vals[0] = vals[0] + alpha * (event.values[0] - vals[0]); vals[1] = vals[1] + alpha * (event.values[1] - vals[1]); vals[2] = vals[2] + alpha * (event.values[2] - vals[2]); character.setX( character.getX() - vals[0] * SENSITIVITY ); }  You can calibrate alpha and SENSITIVITY according to your needs. Now this is why this code was producing very choppy movement initially: in my activity's onResume() I was registering my listener using SensorEvent.SENSOR_DELAY_NORMAL. That is wrong. What you have to do is register it with SensorEvent.SENSOR_DELAY_GAME. I think the reason behind this is obvious. So in your activity's onResume(): sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);