可能重复:Android getOrientation Azimuth gets polluted when phone is tilted
我是Android开发的新手,我试图让用户面对。
在网上搜索后,我很确定我需要使用remapCoordinateSystem
,Android文档说它可以用于增强现实应用。
我尝试使用一些现有代码来确保这是一个好方法。
(最后我想创建一个增强现实应用程序)
以下代码应返回面向学位的用户:
Sensor sensor = event.sensor;
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = event.values.clone();
}else if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = event.values.clone();
}
if (gravity != null && geomagnetic != null){
_rM = SensorManager.getRotationMatrix (R, null, gravity, geomagnetic);
if(_rM){
int mScreenRotation = activity.getWindowManager().getDefaultDisplay().getRotation(); // get user orientation mode
switch (mScreenRotation) { // Handle device rotation (landscape, portrait)
case Surface.ROTATION_0:
axisX = SensorManager.AXIS_X;
axisY = SensorManager.AXIS_Y;
break;
case Surface.ROTATION_90:
axisX = SensorManager.AXIS_Y;
axisY = SensorManager.AXIS_MINUS_X;
break;
case Surface.ROTATION_180: // not handled by my phone so I can't test
axisX = SensorManager.AXIS_MINUS_X;
axisY = SensorManager.AXIS_MINUS_Y;
break;
case Surface.ROTATION_270:
axisX = SensorManager.AXIS_MINUS_Y;
axisY = SensorManager.AXIS_X;
break;
default:
break;
}
SensorManager.remapCoordinateSystem (R, axisX, axisY, outR);
SensorManager.getOrientation (outR, gO);
}
}
userFacing = (float) Math.toDegrees(gO[0]); // Radian to degree
if(userFacing<0) { userFacing+=360; } // -180;180 to 0;360
return userFacing;
实际上,当手机朝下时,我可以获得准确的指南针,但是当我尝试移动手机时(就像用户一样),结果非常不准确:当我倾斜设备时,方向可以移动40°...
但如果我保持倾斜,结果再次不准确(这是平均值,所以这是正常的!) 我需要指南针随时工作......
我想我会使用TYPE_GYROSCOPE
,但现在并非所有设备都有陀螺仪,所以我需要为所有其他设备提供另一种解决方案!
希望你能理解我的问题,抱歉我的英语不好! (我是法国人)
好的,所以在iOS上调整应用程序后,我决定检查android方法是否和我一样好。一个月前,我发布了一个解决方案,这是非常错误的。我在remapCoordinateSystem
上犯了一个大错:我使用AXIS_X
和AXIS_Y
来获取我的矩阵,并尝试用不同的值更正我的值。正如@HoanNguyen建议的那样,我们只需要使用AXIS_X
和AXIS_Z
,然后android处理其余部分。
所以这是最终的代码。更短更容易:
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
gravity = lowPass(event.values.clone(), gravity);
}
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
geomagnetic = lowPass(event.values.clone(), geomagnetic);
}
if (geomagnetic != null && gravity != null) {
if (SensorManager.getRotationMatrix (R_in, null, gravity, geomagnetic)) {
SensorManager.remapCoordinateSystem (R_in, SensorManager.AXIS_X, SensorManager.AXIS_Z, R_out);
SensorManager.getOrientation (R_out, gO);
}
}
为了获得磁北,你必须使用像gO[0]
这样的heading = gO[0];
(注意,返回值以弧度表示)
希望有人在这里!
答案 0 :(得分:3)
如果“面向电话”意味着设备z坐标的方向相反,那么您的代码和您找到的解决方案都是错误的。对于增强现实,您只需致电
remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);
独立于设备方向。然后调用getOrientation()的方位角给出了相对于Magnetic North的电话方向。
这两个调用相当于将设备z坐标投影到世界坐标的XY平面,然后计算结果矢量的方向。