安卓方向传感器的替代品是什么?

17

你好,我正在为Android开发一个3D游戏。

我目前正在尝试向我的游戏添加一个传感器,使玩家可以通过倾斜安卓设备来控制游戏。

理想情况下,我想使用ORIENTATION传感器,但我注意到它已经被弃用。有人知道如何检测安卓的倾斜,并且不使用这个传感器吗?

1个回答

46

实际上,没有“方向”传感器 - 这实际上是一个组合传感器,由加速度计和磁力计结合生成。

来自http://developer.android.com/reference/android/hardware/SensorEvent.html

“此传感器类型存在遗留原因,请改为使用getRotationMatrix()remapCoordinateSystem()getOrientation()来计算这些值。”

public class OrientationTestActivity extends Activity implements SensorEventListener
{
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;

    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;

    private float[] mR = new float[9];
    private float[] mOrientation = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    }

    protected void onResume() {
        super.onResume();
        mLastAccelerometerSet = false;
        mLastMagnetometerSet = false;
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            SensorManager.getOrientation(mR, mOrientation);
            Log.i("OrientationTestActivity", String.format("Orientation: %f, %f, %f",
                                                           mOrientation[0], mOrientation[1], mOrientation[2]));
        }
    }
}

有没有办法像其他传感器一样使用 getOrientation() 命令作为事件处理程序? - user1207381
4
getOrientation()函数需要从getRotationMatrix()函数获取值,而该函数需要磁力计和加速度传感器的值。因此,您需要设置这两个传感器的监听器,并缓存所获得的值。然后,当您获取任一传感器的新数据时,即可重新计算方向。 - JesusFreke
这些方法如何一起使用的示例代码?我找不到任何同时使用这些方法的示例。 - user1207381
这些是很好的建议,我尝试了类似的方法。问题在于我得到的值看起来像角度,但是跳动不定且有点不一致。我想知道当你使用这个传感器时是否曾经遇到过类似的情况? - user1207381
1
加速度计和磁力计传感器往往会有较大的噪声。您可以尝试使用滑动平均来帮助平滑处理。 - JesusFreke
为了平滑数值,我使用了一个滑动平均算法:runningValue = runningValue*(1-epsilon) +rawValue*epsilon; 其中 epsilon<1.0。 - Anarchofascist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接