Skip to content

Instantly share code, notes, and snippets.

@DhimanDasgupta
Last active November 11, 2015 10:13
Show Gist options
  • Save DhimanDasgupta/99ead16fa6ce6dd78271 to your computer and use it in GitHub Desktop.
Save DhimanDasgupta/99ead16fa6ce6dd78271 to your computer and use it in GitHub Desktop.
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.Surface;
import android.view.WindowManager;
public class RotationSensorEventListener implements SensorEventListener {
public interface RotationSensorCallback {
void onOrientationChanged(float azimuth, float pitch, float roll);
}
private static final int SENSOR_DELAY_MICROS = 50 * 1000; // 50ms
private final SensorManager mSensorManager;
private final Sensor mRotationSensor;
private final WindowManager mWindowManager;
private int mLastAccuracy;
private RotationSensorCallback mRotationSensorCallback;
private float[] mRotationMatrix = new float[9];
private float[] mAdjustedRotationMatrix = new float[9];
private float[] mOrientation = new float[3];
public RotationSensorEventListener(SensorManager sensorManager,
WindowManager windowManager) {
mSensorManager = sensorManager;
mWindowManager = windowManager;
// Can be null if the sensor hardware is not available
mRotationSensor = mSensorManager
.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
public void startListening(RotationSensorCallback listener) {
if (mRotationSensorCallback == listener) {
return;
}
mRotationSensorCallback = listener;
if (mRotationSensor == null) {
Log.w("Rotation vector sensor not available; will not provide orientation data.");
return;
}
mSensorManager.registerListener(this, mRotationSensor,
SENSOR_DELAY_MICROS);
}
public void stopListening() {
mSensorManager.unregisterListener(this);
mRotationSensorCallback = null;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
if (mLastAccuracy != accuracy) {
mLastAccuracy = accuracy;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mRotationSensorCallback == null) {
return;
}
if (mLastAccuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
return;
}
if (event.sensor == mRotationSensor) {
updateOrientation(event.values);
}
}
private void updateOrientation(float[] rotationVector) {
// float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(mRotationMatrix,
rotationVector);
// By default, remap the axes as if the front of the
// device screen was the instrument panel.
int worldAxisForDeviceAxisX = SensorManager.AXIS_X;
int worldAxisForDeviceAxisY = SensorManager.AXIS_Z;
// Adjust the rotation matrix for the device orientation
int screenRotation = mWindowManager.getDefaultDisplay().getRotation();
switch (screenRotation) {
case Surface.ROTATION_0:
worldAxisForDeviceAxisX = SensorManager.AXIS_X;
worldAxisForDeviceAxisY = SensorManager.AXIS_Z;
break;
case Surface.ROTATION_90:
worldAxisForDeviceAxisX = SensorManager.AXIS_Z;
worldAxisForDeviceAxisY = SensorManager.AXIS_MINUS_X;
break;
case Surface.ROTATION_180:
worldAxisForDeviceAxisX = SensorManager.AXIS_MINUS_X;
worldAxisForDeviceAxisY = SensorManager.AXIS_MINUS_Z;
break;
case Surface.ROTATION_270:
worldAxisForDeviceAxisX = SensorManager.AXIS_MINUS_Z;
worldAxisForDeviceAxisY = SensorManager.AXIS_X;
break;
}
// float[] adjustedRotationMatrix = new float[9];
SensorManager.remapCoordinateSystem(mRotationMatrix,
worldAxisForDeviceAxisX, worldAxisForDeviceAxisY,
mAdjustedRotationMatrix);
// Transform rotation matrix into azimuth/pitch/roll
// float[] orientation = new float[3];
SensorManager.getOrientation(mAdjustedRotationMatrix, mOrientation);
// Convert radians to degrees
/*
* float azimuth = mOrientation[0] * -57;
* float pitch = mOrientation[1] * -57;
* float roll = mOrientation[2] * -57;
*/
float azimuth = (float) Math.toDegrees(mOrientation[0]);
float pitch = (float) Math.toDegrees(mOrientation[1]);
float roll = (float) Math.toDegrees(mOrientation[2]);
mRotationSensorCallback.onOrientationChanged(azimuth, pitch, roll);
}
}
@DhimanDasgupta
Copy link
Author

How to get proper data from Android Rotation sensor, independent of device orientation and device default sensor co-ordinate system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment