我想要发生的是,当手机远离它的“自然”方向时,重新映射坐标系。因此,当使用手机时,它应该是横向的,它应该读取相同的值,就像它是以肖像方式保存一样。
我正在检查旋转是否等于Surface.ROTATION_90
,如果是,则重新映射坐标系。
我承认我不太了解如何正确地做到这一点,并且可以使用一些指导。
因此,您需要运行以下两种方法:
SensorManager.getRotationMatrix(inR, I, grav, mag);
SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_Y,SensorManager.AXIS_MINUS_X, outR);
传递这些方法需要什么?我创建了一个新的float数组,然后只将orientationsensor数据传递给了mag字段,这个字段无效。所以,我注册了加速度计和磁场传感器。将这两者中的数据提供给getRotatioMatrix
方法,并且我总是得到NullPointerException
(即使JavaDoc说某些参数可以为null)。我甚至尝试将数据传递给每个参数,但仍然得到NullPointerException
。
我的问题是,我需要传递给getRotationMatrix方法的正确数据是什么?
答案 0 :(得分:6)
我发现执行此操作的一种非常简单的方法是SDK示例 AccelerometerPlay 中使用的方法。
首先你得到这样的显示,例如onResume():
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mDisplay = windowManager.getDefaultDisplay();
然后在onSensorChanged()中你可以使用这个简单的代码:
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
switch (mDisplay.getRotation()) {
case Surface.ROTATION_0:
mSensorX = event.values[0];
mSensorY = event.values[1];
break;
case Surface.ROTATION_90:
mSensorX = -event.values[1];
mSensorY = event.values[0];
break;
case Surface.ROTATION_180:
mSensorX = -event.values[0];
mSensorY = -event.values[1];
break;
case Surface.ROTATION_270:
mSensorX = event.values[1];
mSensorY = -event.values[0];
break;
}
}
希望这会有所帮助。
答案 1 :(得分:0)
这是我的代码,它可以在没有NPE的情况下运行。请注意,我只有一个Listener,但你必须注册它才能听两个传感器(ACCELEROMETER和MAGNETICFIELD)。
private SensorEventListener mOrientationSensorsListener = new SensorEventListener() {
private float[] mR = new float[9];
private float[] mRemappedR = new float[9];
private float[] mGeomagneticVector = new float[3];
private float[] mGravityVector = new float[3];
@Override
public void onSensorChanged(SensorEvent event) {
synchronized(this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravityVector = Util.exponentialSmoothing(event.values, mGravityVector, 0.2f);
} else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
mGeomagneticVector = Util.exponentialSmoothing(event.values, mGeomagneticVector, 0.5f);
SensorManager.getRotationMatrix(mR, null, mGravityVector, mGeomagneticVector);
SensorManager.remapCoordinateSystem(mR, SensorManager.AXIS_Y,SensorManager.AXIS_MINUS_X, mRemappedR);
}
}
}
exponentialSmoothing
方法对传感器结果进行了一些平滑处理,看起来就是这样(alpha值可以从0变为1,其中1表示根本没有平滑):
public static float[] exponentialSmoothing(float[] input, float[] output, float alpha) {
for (int i=0; i<input.length; i++) {
output[i] = output[i] + alpha * (input[i] - output[i]);
}
return output;
}
对于synchronized
位 - 我不确定是否需要它,只需在某处阅读并添加它。