安卓:为什么getrotationmatrix返回false?

5

我想获取手机的方向,而我找到了很多人使用的这段代码。以下是代码:

    public void onSensorChanged(SensorEvent event) {
    //if the data sensor is unreliabel
    if(event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        return;

    //gets the value
    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        gravity = event.values.clone();
        break;

    case Sensor.TYPE_MAGNETIC_FIELD:
        geomag = event.values.clone();
        break;
    }
    getOrientation();
}

private void getOrientation(){

    //if gravity n geomag have value, find the rotation matrix
            if(gravity != null && geomag != null){

                //check the rotation matrix found
                boolean success = SensorManager.getRotationMatrix(inR, I, gravity, geomag);

                if(success){
                    SensorManager.getOrientation(inR, orientVals);
                    azimuth = Math.toDegrees(orientVals[0]);

                    TextView azi = (TextView) findViewById(R.id.textAzi);
                    azi.setText("azi : " + azimuth);

                }
                TextView cek = (TextView) findViewById(R.id.cek);
                cek.setText("rotation: "+success);
            }   

但为什么getrotationmatrix总是返回false呢?问题出在哪里?


你尝试过显示(或记录)重力向量的值吗?如果它们接近于零,使得向量的范数接近于零,它将返回false - 就像在自由落体条件下一样。顺便说一句,我注意到你没有从加速度数据中滤除重力,并且你需要这样做。你现在正在为'gravity'分配重力+线性加速度。虽然这不应该导致getRotationMatrix()返回false。 - villoren
3个回答

5

我重新尝试并找到了解决方案,但我将代码更改为以下形式

    public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub
    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        for(int i=0; i<3; i++){
            accelValues[i] =  event.values[i];
        }
        if(compassValues[0] != 0)
            ready = true;

        break;

    case Sensor.TYPE_MAGNETIC_FIELD:
        for(int i=0; i<3; i++){
            compassValues[i] = event.values[i];
        }
        if(accelValues[2] != 0)
            ready = true;

        break;
    }

    if(!ready)
        return;

    boolean cek = SensorManager.getRotationMatrix(inR, inclineMatrix, accelValues, compassValues);

    if(cek){
        SensorManager.getOrientation(inR, prefValues);
        mInclination = SensorManager.getInclination(inclineMatrix);

        //display every 30th values
        if(counter++ % 30 == 0){
            //do your code, what you want to do to the result
            counter = 1;
        }
    }

一切正常运作良好


说实话,我不明白为什么这个会起作用而你的代码却不行。@qwertzguy 如果你得到了正确的值,那么第一段代码也应该可以工作。 - Loolooii

3

请确保已将监听器注册以监听加速度计、磁场和陀螺仪(可选)。您可以在onResume方法中执行此操作。如果您忘记执行此操作,则调用getRotationMatrix时会返回“false”值。

希望这可以帮到您!

   protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

   mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

   // do more staff here..
   }


   protected void onResume() {
    super.onResume();

    mSensorManager.registerListener(
            this, 
            mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
             SensorManager.SENSOR_DELAY_NORMAL );
          mSensorManager.registerListener(
            this, 
            mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), 
            SensorManager.SENSOR_DELAY_NORMAL );
          mSensorManager.registerListener(
                this, 
                mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), 
                SensorManager.SENSOR_DELAY_NORMAL );


}

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

注册陀螺仪对我来说起了作用。在一些手机上一切都正常,但在其他手机上,我无法得到一致的读数。注册陀螺仪(即使我们没有使用其值)解决了这个问题。 - TalL

0

问题出在这段代码:

if(event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
    return;

对于加速度计事件的精度,返回SensorManager.SENSOR_STATUS_UNRELIABLE,这就是为什么重力始终为空的原因。


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