Java 如果手机移动缓慢,旋转传感器不会做出反应

Java 如果手机移动缓慢,旋转传感器不会做出反应,java,android,sensormanager,Java,Android,Sensormanager,我正在尝试从传感器管理器读取方位角、俯仰和滚动。由于某些原因,如果我移动手机非常缓慢,方位角、俯仰和滚动值不会更新,它们只会在我移动手机的力度足够大时更新。换句话说,如果我把手机移动得很慢,我可以旋转90度而不会得到任何新的值 我看到它在这条线上被“卡住”,如果手机移动太慢,这条线将返回false: SensorManager.getRotationMatrix( R, I, mGravity, mGeomagnetic ); 看起来,如果加速器没有明显的力,那么旋转也不会更新 这是我的密码:

我正在尝试从传感器管理器读取方位角、俯仰和滚动。由于某些原因,如果我移动手机非常缓慢,方位角、俯仰和滚动值不会更新,它们只会在我移动手机的力度足够大时更新。换句话说,如果我把手机移动得很慢,我可以旋转90度而不会得到任何新的值

我看到它在这条线上被“卡住”,如果手机移动太慢,这条线将返回false:

SensorManager.getRotationMatrix( R, I, mGravity, mGeomagnetic );
看起来,如果加速器没有明显的力,那么旋转也不会更新

这是我的密码:

mSensorManager = (SensorManager)activityContext.getSystemService(Context.SENSOR_SERVICE);;
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
mMagnetometer  = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mMagnetometer,  SensorManager.SENSOR_DELAY_GAME); 
以下是onSensorChanged事件:

@Override
public void onSensorChanged(SensorEvent event) 
{
    if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION)
        mGravity     = event.values;
    if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)
        mGeomagnetic = event.values;

    if (mGravity != null && mGeomagnetic != null) 
    {
        // The code is triggering to this point fine

        float R[] = new float[9];
        float I[] = new float[9];

        float forceX = Float.valueOf(((float)((float)mGravity[0] ) ) ) / (float)4.0;
        float forceY = Float.valueOf(((float)((float)mGravity[1] ) ) ) / (float)4.0;
        float forceZ = Float.valueOf(((float)((float)mGravity[2] ) ) ) / (float)4.0;

        boolean success = SensorManager.getRotationMatrix( R, I, mGravity, mGeomagnetic );

        if (success) // <-- this is only triggering if phone is moved fast enough 
        {
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);

            rotation_degrees_x = ((float)Math.toDegrees( orientation[0] ) + (float)180.0 ) / (float)360.0;
            rotation_degrees_y = ((float)Math.toDegrees( orientation[1] ) + (float)180.0 ) / (float)360.0;
            rotation_degrees_z = ((float)Math.toDegrees( orientation[2] ) + (float)180.0 ) / (float)360.0;

        }

        mGeomagnetic = null;
        mGravity     = null;
    }
}
因此,我在条件中添加了以下行:

Log.d( "ROTATIONDEBUG", "TYPE_MAGNETIC_FIELD: " + mGeomagnetic[0] + "\t" + mGeomagnetic[1] + "\t" + mGeomagnetic[1] );
得到了一些反映旋转中最细微变化的值:

TYPE_MAGNETIC_FIELD: 23.5      20.7    20.7
TYPE_MAGNETIC_FIELD: 23.2      22.2    22.2
TYPE_MAGNETIC_FIELD: 23.0      24.9    24.9
TYPE_MAGNETIC_FIELD: 22.4      27.5    27.5
TYPE_MAGNETIC_FIELD: 21.5      29.2    29.2
TYPE_MAGNETIC_FIELD: 21.6      30.2    30.2
TYPE_MAGNETIC_FIELD: 21.1      32.1    32.10
TYPE_MAGNETIC_FIELD: 20.7      34.8    34.8
TYPE_MAGNETIC_FIELD: 20.7      34.7    34.7
TYPE_MAGNETIC_FIELD: 20.9      35.0    35.0
TYPE_MAGNETIC_FIELD: 20.6      36.0    36.0
但无法理解它们为什么不一起工作,SensorManager.getRotationMatrix行返回false

我下载了一些指南针和传感器测试应用程序,所有这些应用程序都可以检测到这种光线运动,所以我猜我的代码有问题

编辑: 我尝试了一个不同的代码示例,但它给出了完全相同的结果:

SensorEventListener sensorEventListener = new SensorEventListener() {
    float[] mGravity;
    float[] mGeomagnetic;

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
            mGravity = event.values;
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
            mGeomagnetic = event.values;
        if (mGravity != null && mGeomagnetic != null) {
            float R[] = new float[9];
            float I[] = new float[9];
            boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
            if (success) {
                float orientationData[] = new float[3];
                SensorManager.getOrientation(R, orientationData);
                azimuth = orientationData[0];
                pitch = orientationData[1];
                roll = orientationData[2];
            }
        }
    }
};
到目前为止,我看到了这种模式:

如果我直接从以下条件中读取值,我可以获得“详细/敏感”更改:

 if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) 
    mGeomagnetic = event.values; 
但如果我尝试使用getRotationMatrix,它将仅在加速计检测到足够的力时返回true:

 boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
如何使SensorManager.getRotationMatrix在不考虑加速计值的情况下触发?或者如何将这些原始值转换为度


有什么提示吗?谢谢大家!

将SENSOR_DELAY_游戏改为SENSOR_DELAY_NORMAL,只使用常规类型的陀螺仪,解决了这个问题,即使是最轻微的移动,它也会触发

请参阅和
“由于游戏旋转矢量传感器不使用磁场,相对旋转更精确,且不受磁场变化的影响。如果您不关心north在哪里,并且法线旋转矢量因依赖磁场而不适合您的需要,请在游戏中使用此传感器。”
@JonGoodwin感谢您的回复!在将传感器类型更改为“游戏旋转向量”类型后,它现在触发良好,但我想我关心的是北方在哪里,好像我将手机竖直,朝一个方向倾斜,然后朝另一个方向倾斜,在将手机移动90 X轴时做同样的操作,结果是不同的。有没有办法把两者结合起来?磁北和“快速触发”?谢谢好的,我终于能够让它触发了,把SENSOR_DELAY_游戏改为SENSOR_DELAY_NORMAL,只使用普通类型的陀螺仪,像个魔术师一样工作!酷,你现在是专家了!回答您自己的问题,以便其他人可以看到该技术。祝你好运
 boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);