下面列出了android.hardware.Sensor#TYPE_GRAVITY 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
updateSensorData(latestSampledData.accelerate, event);
} else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
updateSensorData(latestSampledData.gyroscope, event);
} else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
updateSensorData(latestSampledData.gravity, event);
} else if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
latestSampledData.light = event.values[0];
} else if (event.sensor.getType() == Sensor.TYPE_PRESSURE) {
latestSampledData.pressure = event.values[0];
} else if (event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
latestSampledData.temperature = event.values[0];
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
updateSensorData(latestSampledData.magnetic, event);
} else if (event.sensor.getType() == Sensor.TYPE_GAME_ROTATION_VECTOR) {
updateSensorData(latestSampledData.game_rotation_vector, event);
}
}
private void processSensorData(final SensorEvent sensorEvent) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mAccellX = sensorEvent.values[0];
mAccellY = sensorEvent.values[1];
mAccellZ = sensorEvent.values[2];
mIsAccellReady.compareAndSet(false, true);
} else if (sensorEvent.sensor.getType() == Sensor.TYPE_GRAVITY) {
mGravityX = sensorEvent.values[0];
mGravityY = sensorEvent.values[1];
mGravityZ = sensorEvent.values[2];
mIsGravityReady.compareAndSet(false, true);
} else if (sensorEvent.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
mGyroX = Math.toDegrees(sensorEvent.values[0]);
mGyroY = Math.toDegrees(sensorEvent.values[1]);
mGyroZ = Math.toDegrees(sensorEvent.values[2]);
mIsGyroReady.compareAndSet(false, true);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
// we received a sensor event. it is a good practice to check
// that we received the proper event
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magnitudeValues = event.values.clone();
} else if (event.sensor.getType() == Sensor.TYPE_GRAVITY) {
gravityValues = event.values.clone();
}
if (magnitudeValues != null && gravityValues != null) {
float[] i = new float[16];
// Fuse gravity-sensor (virtual sensor) with compass
SensorManager.getRotationMatrix(currentOrientationRotationMatrix.matrix, i, gravityValues, magnitudeValues);
// Transform rotation matrix to quaternion
currentOrientationQuaternion.setRowMajor(currentOrientationRotationMatrix.matrix);
}
}
/**
* 磁気センサー・加速度センサー等を読み取り開始
*/
public void start() {
synchronized (mSync) {
final Context context = mWeakContext.get();
if ((mSensorManager == null) || (context == null)) {
throw new IllegalStateException("already released");
}
for (int i = 0; i < 3; i++) {
mMagnetValues[i] = mGravityValues[i] = mAzimuthValues[i] = 0;
mAccelValues[i] = mGyroValues[i] = 0;
}
// 重力センサーがあればそれを使う。なければ加速度センサーで代用する
boolean hasGravity = false;
mRegistered = true;
for (final int sensor_type : SENSOR_TYPES) {
final List<Sensor> sensors = mSensorManager.getSensorList(sensor_type);
if ((sensors != null) && (sensors.size() > 0)) {
if (sensor_type == Sensor.TYPE_GRAVITY) {
Log.i(TAG, "hasGravity");
hasGravity = true;
}
if (!hasGravity || (sensor_type != Sensor.TYPE_ACCELEROMETER)) {
mSensorManager.registerListener(mSensorEventListener, sensors.get(0),
SensorManager.SENSOR_DELAY_GAME);
}
} else {
Log.i(TAG, String.format("no sensor for sensor type %d", sensor_type));
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
int SensorType = sensor.getType();
switch (SensorType) {
case Sensor.TYPE_GRAVITY:
m_GravityAccuracy = accuracy;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
m_MagneticFieldAccuracy = accuracy;
break;
}
if (m_parent != null) m_parent.onAccuracyChanged(sensor, accuracy);
}
GravityUpdatesProvider(int sensorDelay) {
super(Sensor.TYPE_GRAVITY, sensorDelay);
}
public PGravity(AppRunner appRunner) {
super(appRunner);
type = Sensor.TYPE_GRAVITY;
}
/**
* センサーの値が変化した時のコールバック
* @param event
*/
@Override
public void onSensorChanged(final SensorEvent event) {
if (DEBUG) Log.v(TAG, "onSensorChanged:" + event);
final float[] values = event.values;
final int type = event.sensor.getType();
switch (type) {
case Sensor.TYPE_MAGNETIC_FIELD: // 磁気センサー
synchronized (mSensorSync) {
// ハイパスフィルターを通して取得
// alpha=t/(t+dt), dt≒[email protected]_DELAY_GAME, tはローパスフィルタの時定数(t=80)
highPassFilter(mMagnetValues, values, 0.8f);
System.arraycopy(values, 0, mMagnetValues, 0, 3);
// 磁気センサーの値と重力センサーの値から方位を計算
SensorManager.getRotationMatrix(mRotateMatrix, mInclinationMatrix, mGravityValues, mMagnetValues);
getOrientation(mRotateMatrix, mAzimuthValues);
mAzimuthValues[0] *= TO_DEGREE;
mAzimuthValues[1] *= TO_DEGREE;
mAzimuthValues[2] *= TO_DEGREE;
}
break;
case Sensor.TYPE_GRAVITY: // 重力センサー
synchronized (mSensorSync) {
System.arraycopy(values, 0, mGravityValues, 0, 3);
}
break;
case Sensor.TYPE_ACCELEROMETER: // 加速度センサー
synchronized (mSensorSync) {
System.arraycopy(values, 0, mAccelValues, 0, 3);
System.arraycopy(values, 0, mGravityValues, 0, 3); // 重力センサーが無い時は加速度センサーで代用
}
break;
case Sensor.TYPE_GYROSCOPE: // ジャイロセンサー
synchronized (mSensorSync) {
System.arraycopy(values, 0, mGyroValues, 0, 3);
}
break;
default:
if (DEBUG) Log.v(TAG, "onSensorChanged:" + String.format(Locale.US, "その他%d(%f,%f,%f)", type, values[0], values[1], values[2]));
break;
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (use_gravity) {
final Sensor source = event.sensor;
if (source.getType() == Sensor.TYPE_GRAVITY) {
// final float z = event.values[2];
final float y = event.values[1];
final float x = event.values[0];
// calculate angle from gravity sensor only
float rotation = (y * 9) - 90;
if (rotation < 0) {
if (x > 0) {
rotation = 0 - rotation;
}
}
// normalize 0-360
rotation = rotation + 180;
final int window_rotation = getWindowManager().getDefaultDisplay().getRotation();
// compensate for view rotation
switch (window_rotation) {
case Surface.ROTATION_90:
rotation += 270;
break;
case Surface.ROTATION_180:
rotation += 180;
break;
case Surface.ROTATION_270:
rotation += 90;
break;
}
// snap to nearest 90 degree
final float adjust_rotation = ((int) (((rotation + 225) % 360) / 90)) * 90;
// update rotation if something changed
if (adjust_rotation != last_rotation) {
last_rotation = adjust_rotation;
JoH.runOnUiThread(new Runnable() {
@Override
public void run() {
image.setRotation(adjust_rotation);
graphimage.setRotation(adjust_rotation);
inflatedLayout.setRotation(adjust_rotation);
}
});
}
}
} else {
Log.e(TAG, "Got sensor data when sensor should be disabled");
unregister_sensor_receiver();
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (use_gravity) {
final Sensor source = event.sensor;
if (source.getType() == Sensor.TYPE_GRAVITY) {
// final float z = event.values[2];
final float y = event.values[1];
final float x = event.values[0];
// calculate angle from gravity sensor only
float rotation = (y * 9) - 90;
if (rotation < 0) {
if (x > 0) {
rotation = 0 - rotation;
}
}
// normalize 0-360
rotation = rotation + 180;
final int window_rotation = getWindowManager().getDefaultDisplay().getRotation();
// compensate for view rotation
switch (window_rotation) {
case Surface.ROTATION_90:
rotation += 270;
break;
case Surface.ROTATION_180:
rotation += 180;
break;
case Surface.ROTATION_270:
rotation += 90;
break;
}
// snap to nearest 90 degree
final float adjust_rotation = ((int) (((rotation + 225) % 360) / 90)) * 90;
// update rotation if something changed
if (adjust_rotation != last_rotation) {
last_rotation = adjust_rotation;
JoH.runOnUiThread(new Runnable() {
@Override
public void run() {
image.setRotation(adjust_rotation);
graphimage.setRotation(adjust_rotation);
inflatedLayout.setRotation(adjust_rotation);
}
});
}
}
} else {
Log.e(TAG, "Got sensor data when sensor should be disabled");
unregister_sensor_receiver();
}
}
public static String[] getLabelsForSensor(Context context, Sensor sensor) {
String[] labels;
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
labels = context.getResources().getStringArray(R.array.accelerometer_values);
break;
case Sensor.TYPE_AMBIENT_TEMPERATURE:
labels = context.getResources().getStringArray(R.array.ambient_temperature_values);
break;
case Sensor.TYPE_GAME_ROTATION_VECTOR:
labels = context.getResources().getStringArray(R.array.game_rotation_vector_values);
break;
case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
labels = context.getResources().getStringArray(R.array.rotation_vector_values);
break;
case Sensor.TYPE_GRAVITY:
labels = context.getResources().getStringArray(R.array.gravity_values);
break;
case Sensor.TYPE_GYROSCOPE:
labels = context.getResources().getStringArray(R.array.gyroscore_values);
break;
case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
labels = context.getResources().getStringArray(R.array.gyroscore_uncalibrated_values);
break;
case Sensor.TYPE_HEART_RATE:
labels = context.getResources().getStringArray(R.array.heart_rate_values);
break;
case Sensor.TYPE_LIGHT:
labels = context.getResources().getStringArray(R.array.light_values);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
labels = context.getResources().getStringArray(R.array.linear_acceleration_values);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
labels = context.getResources().getStringArray(R.array.magnetic_values);
break;
case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
labels = context.getResources().getStringArray(R.array.magnetic_field_uncalibrated_values);
break;
case Sensor.TYPE_PRESSURE:
labels = context.getResources().getStringArray(R.array.pressure_values);
break;
case Sensor.TYPE_PROXIMITY:
labels = context.getResources().getStringArray(R.array.proximity_values);
break;
case Sensor.TYPE_RELATIVE_HUMIDITY:
labels = context.getResources().getStringArray(R.array.relative_humidity_values);
break;
case Sensor.TYPE_ROTATION_VECTOR:
labels = context.getResources().getStringArray(R.array.rotation_vector_values);
break;
case Sensor.TYPE_STEP_COUNTER:
labels = context.getResources().getStringArray(R.array.step_counter_values);
break;
default:
labels = new String[]{};
}
return labels;
}
@Nullable
public static String getHumanStringType(Sensor sensor) {
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
return "Accelerometer";
case Sensor.TYPE_AMBIENT_TEMPERATURE:
return "Ambient Temperature";
case Sensor.TYPE_GAME_ROTATION_VECTOR:
return "Game Rotation Vector";
case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
return "Geomagnetic Rotation Vector";
case Sensor.TYPE_GRAVITY:
return "Gravity";
case Sensor.TYPE_GYROSCOPE:
return "Gyroscope";
case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
return "Gyroscope (Uncalibrated)";
case Sensor.TYPE_HEART_RATE:
return "Heart Rate";
case Sensor.TYPE_LIGHT:
return "Light";
case Sensor.TYPE_LINEAR_ACCELERATION:
return "Linear Acceleration";
case Sensor.TYPE_MAGNETIC_FIELD:
return "Magnetic Field";
case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
return "Magnetic Field (Uncalibrated)";
case Sensor.TYPE_PRESSURE:
return "Pressure";
case Sensor.TYPE_PROXIMITY:
return "Proximity";
case Sensor.TYPE_RELATIVE_HUMIDITY:
return "Relative Humidity";
case Sensor.TYPE_ROTATION_VECTOR:
return "Rotation Vector";
case Sensor.TYPE_SIGNIFICANT_MOTION:
return "Significant Motion";
case Sensor.TYPE_STEP_COUNTER:
return "Step Counter";
case Sensor.TYPE_STEP_DETECTOR:
return "Step Detector";
case Sensor.TYPE_ORIENTATION:
return "Orientation";
case Sensor.TYPE_TEMPERATURE:
return "Temperature";
}
return null;
}
public static String getDescription(Sensor sensor) {
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
return "Measures the acceleration force in m/s² that is applied to a device on all three physical axes (x, y, and z), including the force of gravity.";
case Sensor.TYPE_AMBIENT_TEMPERATURE:
return "Measures the ambient room temperature in degrees Celsius (°C).";
case Sensor.TYPE_GRAVITY:
return "Measures the force of gravity in m/s² that is applied to a device on all three physical axes (x, y, z).";
case Sensor.TYPE_GYROSCOPE:
return "Measures a device's rate of rotation in rad/s around each of the three physical axes (x, y, and z).";
case Sensor.TYPE_HEART_RATE:
return "Measures heart rate.";
case Sensor.TYPE_LIGHT:
return "Measures the ambient light level (illumination) in lx.";
case Sensor.TYPE_LINEAR_ACCELERATION:
return "Measures the acceleration force in m/s² that is applied to a device on all three physical axes (x, y, and z), excluding the force of gravity.";
case Sensor.TYPE_MAGNETIC_FIELD:
return "Measures the ambient geomagnetic field for all three physical axes (x, y, z) in μT.";
case Sensor.TYPE_PRESSURE:
return "Measures the ambient air pressure in hPa or mbar.";
case Sensor.TYPE_PROXIMITY:
return "Measures the proximity of an object in cm relative to the view screen of a device. This sensor is typically used to determine whether a handset is being held up to a person's ear.";
case Sensor.TYPE_RELATIVE_HUMIDITY:
return "Measures the relative ambient humidity in percent (%).";
case Sensor.TYPE_ROTATION_VECTOR:
return "Measures the orientation of a device by providing the three elements of the device's rotation vector.";
case Sensor.TYPE_ORIENTATION:
return "Measures degrees of rotation that a device makes around all three physical axes (x, y, z). ";
case Sensor.TYPE_TEMPERATURE:
return "Measures the temperature of the device in degrees Celsius (°C). ";
default:
return "Information about this sensor is unavailable.";
}
}
@Override
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ROTATION_VECTOR:
SensorManager.getQuaternionFromVector(latestQuaternion, event.values);
if (!haveRotVecData) {
initialiseDefaultFilters(SMOOTHING_FACTOR_HIGH_ACC);
}
haveRotVecData = true;
break;
case Sensor.TYPE_GRAVITY:
if (haveRotVecData) {
// rotation vector sensor data is better
sensorManager.unregisterListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY));
break;
}
System.arraycopy(event.values, 0, latestAccelerations, 0, 3);
haveGravData = true;
break;
case Sensor.TYPE_ACCELEROMETER:
if (haveGravData || haveRotVecData) {
// rotation vector / gravity sensor data is better!
// let's not listen to the accelerometer anymore
sensorManager.unregisterListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER));
break;
}
System.arraycopy(event.values, 0, latestAccelerations, 0, 3);
haveAccelData = true;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
if (haveRotVecData) {
// rotation vector sensor data is better
sensorManager.unregisterListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD));
break;
}
System.arraycopy(event.values, 0, latestMagFields, 0, 3);
haveMagData = true;
break;
}
if (haveDataNecessaryToComputeOrientation()) {
computeOrientation();
}
}
private void populateTypeField( int type ) {
if( type == 0 || mTypeRow == null || mType == null )
return;
String typeName;
switch( type ) {
case Sensor.TYPE_ACCELEROMETER: {
typeName = "Accelerometer";
break;
}
case Sensor.TYPE_AMBIENT_TEMPERATURE: {
typeName = "Ambient Temperature";
break;
}
case Sensor.TYPE_GAME_ROTATION_VECTOR: {
typeName = "Game Rotation Vector";
break;
}
case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR: {
typeName = "Geomagnetic Rotation Vector";
break;
}
case Sensor.TYPE_GRAVITY: {
typeName = "Gravity";
break;
}
case Sensor.TYPE_GYROSCOPE: {
typeName = "Gyroscope";
break;
}
case Sensor.TYPE_GYROSCOPE_UNCALIBRATED: {
typeName = "Uncalibrated Gyroscope";
break;
}
case Sensor.TYPE_LIGHT: {
typeName = "Light";
break;
}
case Sensor.TYPE_LINEAR_ACCELERATION: {
typeName = "Linear Acceleration";
break;
}
case Sensor.TYPE_MAGNETIC_FIELD: {
typeName = "Magnetic Field";
break;
}
case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED: {
typeName = "Uncalibrated Magnetic Field";
break;
}
case Sensor.TYPE_PRESSURE: {
typeName = "Pressure";
break;
}
case Sensor.TYPE_PROXIMITY: {
typeName = "Proximity";
break;
}
case Sensor.TYPE_RELATIVE_HUMIDITY: {
typeName = "Relative Humidity";
break;
}
case Sensor.TYPE_ROTATION_VECTOR: {
typeName = "Rotation Vector";
break;
}
case Sensor.TYPE_SIGNIFICANT_MOTION: {
typeName = "Significant Motion";
break;
}
case Sensor.TYPE_STEP_COUNTER: {
typeName = "Step Counter";
break;
}
case Sensor.TYPE_STEP_DETECTOR: {
typeName = "Step Detector";
break;
}
default: {
typeName = "Other";
}
}
mType.setText( typeName );
mTypeRow.setVisibility( View.VISIBLE );
}
@SuppressLint("InlinedApi") // There is a check in STEP_DETECTOR and STEP_COUNTER
private static int getSensorType(SKSensorModuleType sensorType) throws SKException{
switch (sensorType) {
case ACCELEROMETER:
return Sensor.TYPE_ACCELEROMETER;
case GRAVITY:
return Sensor.TYPE_GRAVITY;
case LINEAR_ACCELERATION:
return Sensor.TYPE_LINEAR_ACCELERATION;
case GYROSCOPE:
return Sensor.TYPE_GYROSCOPE;
case ROTATION:
return Sensor.TYPE_ROTATION_VECTOR;
case MAGNETOMETER:
return Sensor.TYPE_MAGNETIC_FIELD;
case AMBIENT_TEMPERATURE:
return Sensor.TYPE_AMBIENT_TEMPERATURE;
case STEP_DETECTOR:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return Sensor.TYPE_STEP_DETECTOR;
}
else
{
throw new SKException(TAG, "STEP_DETECTOR requires Android KitKat or greater.", SKExceptionErrorCode.UNKNOWN_ERROR);
}
case STEP_COUNTER:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return Sensor.TYPE_STEP_COUNTER;
}
else
{
throw new SKException(TAG, "STEP_COUNTER requires Android KitKat or greater.", SKExceptionErrorCode.UNKNOWN_ERROR);
}
case LIGHT:
return Sensor.TYPE_LIGHT;
case LOCATION:
case ACTIVITY:
case BATTERY:
throw new SKException(TAG, "Not a native SensorModule.", SKExceptionErrorCode.UNKNOWN_ERROR);
default:
throw new SKException(TAG, "Unknown SensorModule", SKExceptionErrorCode.UNKNOWN_ERROR);
}
}
@SuppressWarnings("deprecation")
private boolean isRestricted(XParam param, int type) throws Throwable {
if (type == Sensor.TYPE_ALL)
return false;
else if (type == Sensor.TYPE_ACCELEROMETER || type == Sensor.TYPE_LINEAR_ACCELERATION) {
if (isRestricted(param, "acceleration"))
return true;
} else if (type == Sensor.TYPE_GRAVITY) {
if (isRestricted(param, "gravity"))
return true;
} else if (type == Sensor.TYPE_RELATIVE_HUMIDITY) {
if (isRestricted(param, "humidity"))
return true;
} else if (type == Sensor.TYPE_LIGHT) {
if (isRestricted(param, "light"))
return true;
} else if (type == Sensor.TYPE_MAGNETIC_FIELD || type == Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED) {
if (isRestricted(param, "magnetic"))
return true;
} else if (type == Sensor.TYPE_SIGNIFICANT_MOTION) {
if (isRestricted(param, "motion"))
return true;
} else if (type == Sensor.TYPE_ORIENTATION || type == Sensor.TYPE_GYROSCOPE
|| type == Sensor.TYPE_GYROSCOPE_UNCALIBRATED) {
if (isRestricted(param, "orientation"))
return true;
} else if (type == Sensor.TYPE_PRESSURE) {
if (isRestricted(param, "pressure"))
return true;
} else if (type == Sensor.TYPE_PROXIMITY) {
if (isRestricted(param, "proximity"))
return true;
} else if (type == Sensor.TYPE_GAME_ROTATION_VECTOR || type == Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR
|| type == Sensor.TYPE_ROTATION_VECTOR) {
if (isRestricted(param, "rotation"))
return true;
} else if (type == Sensor.TYPE_TEMPERATURE || type == Sensor.TYPE_AMBIENT_TEMPERATURE) {
if (isRestricted(param, "temperature"))
return true;
} else if (type == Sensor.TYPE_STEP_COUNTER || type == Sensor.TYPE_STEP_DETECTOR) {
if (isRestricted(param, "step"))
return true;
} else if (type == Sensor.TYPE_HEART_RATE) {
if (isRestricted(param, "heartrate"))
return true;
} else if (type == 22) {
// 22 = TYPE_TILT_DETECTOR
// Do nothing
} else if (type == 23 || type == 24 || type == 25) {
// 23 = TYPE_WAKE_GESTURE
// 24 = TYPE_GLANCE_GESTURE
// 25 = TYPE_PICK_UP_GESTURE
// 23/24 This sensor is expected to only be used by the system ui
// 25 Expected to be used internally for always on display
} else
Util.log(this, Log.WARN, "Unknown sensor type=" + type);
return false;
}
@Override
public void onSensorChanged(SensorEvent evnt) {
try {
if (parentActivity != null) {
int sensorType = evnt.sensor.getType();
switch (sensorType) {
case Sensor.TYPE_GRAVITY:
if (m_NormGravityVector == null) m_NormGravityVector = new float[3];
System.arraycopy(evnt.values, 0, m_NormGravityVector, 0, m_NormGravityVector.length);
m_Norm_Gravity = (float) Math.sqrt(m_NormGravityVector[0] * m_NormGravityVector[0] + m_NormGravityVector[1] * m_NormGravityVector[1] + m_NormGravityVector[2] * m_NormGravityVector[2]);
for (int i = 0; i < m_NormGravityVector.length; i++)
m_NormGravityVector[i] /= m_Norm_Gravity;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
if (m_NormMagFieldValues == null) m_NormMagFieldValues = new float[3];
System.arraycopy(evnt.values, 0, m_NormMagFieldValues, 0, m_NormMagFieldValues.length);
m_Norm_MagField = (float) Math.sqrt(m_NormMagFieldValues[0] * m_NormMagFieldValues[0] + m_NormMagFieldValues[1] * m_NormMagFieldValues[1] + m_NormMagFieldValues[2] * m_NormMagFieldValues[2]);
for (int i = 0; i < m_NormMagFieldValues.length; i++)
m_NormMagFieldValues[i] /= m_Norm_MagField;
break;
}
if (m_NormGravityVector != null && m_NormMagFieldValues != null) {
// first calculate the horizontal vector that points due east
float East_x = m_NormMagFieldValues[1] * m_NormGravityVector[2] - m_NormMagFieldValues[2] * m_NormGravityVector[1];
float East_y = m_NormMagFieldValues[2] * m_NormGravityVector[0] - m_NormMagFieldValues[0] * m_NormGravityVector[2];
float East_z = m_NormMagFieldValues[0] * m_NormGravityVector[1] - m_NormMagFieldValues[1] * m_NormGravityVector[0];
float norm_East = (float) Math.sqrt(East_x * East_x + East_y * East_y + East_z * East_z);
if (m_Norm_Gravity * m_Norm_MagField * norm_East < 0.1f) { // Typical values are > 100.
m_OrientationOK = false; // device is close to free fall (or in space?), or close to magnetic north pole.
} else {
m_NormEastVector[0] = East_x / norm_East;
m_NormEastVector[1] = East_y / norm_East;
m_NormEastVector[2] = East_z / norm_East;
// next calculate the horizontal vector that points due north
float M_dot_G = (m_NormGravityVector[0] * m_NormMagFieldValues[0] + m_NormGravityVector[1] * m_NormMagFieldValues[1] + m_NormGravityVector[2] * m_NormMagFieldValues[2]);
float North_x = m_NormMagFieldValues[0] - m_NormGravityVector[0] * M_dot_G;
float North_y = m_NormMagFieldValues[1] - m_NormGravityVector[1] * M_dot_G;
float North_z = m_NormMagFieldValues[2] - m_NormGravityVector[2] * M_dot_G;
float norm_North = (float) Math.sqrt(North_x * North_x + North_y * North_y + North_z * North_z);
m_NormNorthVector[0] = North_x / norm_North;
m_NormNorthVector[1] = North_y / norm_North;
m_NormNorthVector[2] = North_z / norm_North;
// take account of screen rotation away from its natural rotation
float screen_adjustment = 0;
WindowManager windowManager = parentActivity.getWindowManager();
if (windowManager != null) {
Display defaultDisplay = windowManager.getDefaultDisplay();
if (defaultDisplay != null) {
int rotation = defaultDisplay.getRotation();
switch (rotation) {
case Surface.ROTATION_0:
screen_adjustment = 0;
break;
case Surface.ROTATION_90:
screen_adjustment = (float) Math.PI / 2;
break;
case Surface.ROTATION_180:
screen_adjustment = (float) Math.PI;
break;
case Surface.ROTATION_270:
screen_adjustment = 3 * (float) Math.PI / 2;
break;
}
}
}
// NB: the rotation matrix has now effectively been calculated. It consists of the three vectors m_NormEastVector[], m_NormNorthVector[] and m_NormGravityVector[]
// calculate all the required angles from the rotation matrix
// NB: see http://math.stackexchange.com/questions/381649/whats-the-best-3d-angular-co-ordinate-system-for-working-with-smartfone-apps
float sin = m_NormEastVector[1] - m_NormNorthVector[0], cos = m_NormEastVector[0] + m_NormNorthVector[1];
m_azimuth_radians = (float) (sin != 0 && cos != 0 ? Math.atan2(sin, cos) : 0);
m_pitch_radians = (float) Math.acos(m_NormGravityVector[2]);
sin = -m_NormEastVector[1] - m_NormNorthVector[0];
cos = m_NormEastVector[0] - m_NormNorthVector[1];
float aximuth_plus_two_pitch_axis_radians = (float) (sin != 0 && cos != 0 ? Math.atan2(sin, cos) : 0);
m_pitch_axis_radians = (aximuth_plus_two_pitch_axis_radians - m_azimuth_radians) / 2;
m_azimuth_radians += screen_adjustment;
m_pitch_axis_radians += screen_adjustment;
m_OrientationOK = true;
}
}
if (m_parent != null) m_parent.onSensorChanged(evnt);
}
} catch (Exception e) {
GPLog.error(this, null, e);
}
}
/**
* After {@link #startTracking(int)} has been called and sensor data has been received,
* this method returns the sensor type chosen for orientation calculations.
*
* @return one of {@link Sensor#TYPE_ROTATION_VECTOR}, {@link Sensor#TYPE_GRAVITY},
* {@link Sensor#TYPE_ACCELEROMETER} or 0 if none of the previous are available or
* {@link #startTracking(int)} has not yet been called.
*/
public int getChosenSensorType() {
if (haveRotVecData) return Sensor.TYPE_ROTATION_VECTOR;
if (haveGravData) return Sensor.TYPE_GRAVITY;
if (haveAccelData) return Sensor.TYPE_ACCELEROMETER;
return 0;
}