我旋转手机 - 安卓传感器值保持不变

时间:2014-07-12 08:53:49

标签: android android-sensors

我有一个问题,我已经挣扎了几个星期了。

我有一个使用TYPE_ROTATION_VECTOR传感器的应用。当我在家时总是有效,但当我在外面时,传感器停止工作。我仍然可以调用onSensorChanged,但即使移动或旋转设备,值也保持不变。

到目前为止,我的解决方案是检测值是否在一段时间内保持不变,如果是,我取消注册并重新注册SensorEventListener。然后再次运作。

但为什么会发生这种情况,而且只能在外面? Galaxy S3 Mini(使用Android 4.1)和Nexus 10(使用Android 4.4)都会出现问题。

以下是我的RotationSensor类的代码。 RotationSensor对象是Fragment的成员,具有setRetainInstance(true);.但错误只发生在TYPE_ROTATION_VECTOR传感器上,所以我猜错误必须在下面的代码中。

public class RotationSensor extends OrientationSensor { //The super class is just an abstract class which doesn't do anything
private int screen_rotation=0;
 private SensorManager mSensorManager;
 private Sensor mSensor, magSensor;
 private float[] values = null;
private Activity activity=null;
 private SensorListener listener;
 private float magField=0;

 private float[] orientationValsFlat = new float[3];
 private float[] orientationValsOpp = new float[3];
 private float[] mRotationMatrix = new float[9];
 private float[] matrixI=null;

 private float[] m_NormMagFieldValues = null;


//This method is called from a Fragment's onResume method.
 @Override
 public void register(Activity activity, SensorListener otherListener,int sensorSpeed) {
     this.activity=activity;
     listener=otherListener;
     mSensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
     mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
     if (mSensor==null){ 
         mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
         matrixI= new float[9];
     }
     magSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
     mSensorManager.registerListener(this, mSensor, sensorSpeed);
     mSensorManager.registerListener(this, magSensor, sensorSpeed);
 }

//Called from onPause in a Fragment
 @Override
 public void unregister() {
     activity=null;
     listener=null;
     mSensorManager.unregisterListener (this, mSensor);
     mSensorManager.unregisterListener (this, magSensor);
 }

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    if (activity==null) return;
    if (listener!=null) listener.onAccuracyChanged(sensor, accuracy);
}

@Override
public void onSensorChanged(SensorEvent event) {
    if (activity==null) return;
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) 
    {
        values= event.values.clone();
        SensorManager.getRotationMatrixFromVector(mRotationMatrix, values);

        float[] remapMatrix = new float[9];
        SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapMatrix);
        SensorManager.getOrientation(remapMatrix, orientationValsOpp);
        SensorManager.getOrientation(mRotationMatrix, orientationValsFlat);

        screen_rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
       float screen_adjustment = 0;


       switch(screen_rotation) {
            case Surface.ROTATION_0:   screen_adjustment =          0;         break;
            case Surface.ROTATION_90:  screen_adjustment =   (float)Math.PI/2; break;
            case Surface.ROTATION_180: screen_adjustment =   (float)Math.PI;   break;
            case Surface.ROTATION_270: screen_adjustment = 3*(float)Math.PI/2; break;
        }

       if (screen_rotation==Surface.ROTATION_90 || screen_rotation==Surface.ROTATION_270) arrayswap (orientationValsFlat,1,2);
        orientationValsFlat[0]+=screen_adjustment;
        orientationValsOpp[0]+=screen_adjustment;

    }
    if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
          if (m_NormMagFieldValues == null) m_NormMagFieldValues = new float[3];
            m_NormMagFieldValues=event.values.clone();
         magField = (float)Math.sqrt(m_NormMagFieldValues[0]*m_NormMagFieldValues[0] + m_NormMagFieldValues[1]*m_NormMagFieldValues[1] + m_NormMagFieldValues[2]*m_NormMagFieldValues[2]);
    }
    if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
        values = event.values.clone();

        if (m_NormMagFieldValues!=null && SensorManager.getRotationMatrix(mRotationMatrix, matrixI, values,  m_NormMagFieldValues)){
         SensorManager.getOrientation(mRotationMatrix, orientationValsFlat);
         orientationValsOpp=orientationValsFlat;
        screen_rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
           float screen_adjustment = 0;


           switch(screen_rotation) {
                case Surface.ROTATION_0:   screen_adjustment =          0;         break;
                case Surface.ROTATION_90:  screen_adjustment =   (float)Math.PI/(4); break;
                case Surface.ROTATION_180: screen_adjustment =   (float)Math.PI/(-2);   break;
                case Surface.ROTATION_270: screen_adjustment = 3*(float)Math.PI/4; break;
            }

           if (screen_rotation==Surface.ROTATION_90 || screen_rotation==Surface.ROTATION_270) arrayswap (orientationValsFlat,1,2);

         orientationValsFlat[0]+=screen_adjustment; orientationValsOpp[0]+=screen_adjustment;
        }
    }


    if (listener!=null) listener.onSensorChanged(this,event); 
}

@Override
public int getField(){
    return (int)magField;
}

@Override
public double getAzimuth() {
    boolean opp =(screen_rotation==Surface.ROTATION_0 && Math.toDegrees(getPitch())<-50);
    if (opp)
        return orientationValsOpp[0];
    else
        return orientationValsFlat[0];
  }

@Override
public double getPitch() {
    return orientationValsFlat[1];
}

@Override
public double getRoll() {
    return orientationValsFlat[2];
}

private void arrayswap (float[] array, int index1, int index2){
    float temp= array[index1];
    array[index1]=array[index2];
    array[index2]=temp;
}

}

 public interface SensorListener {
     public void onSensorChanged(OrientationSensor os, SensorEvent event);
     public void onAccuracyChanged(Sensor sensor, int accuracy);
}

1 个答案:

答案 0 :(得分:-1)

可能性可能是:在关闭应用程序之前,您可能没有unregister() sensorEventListener。因此,sensorManager会在您的日志中收到onSensorChanged()个事件。

在应用程序关闭之前,您只需要unregisterListener()。您可以使用onPause()活动方法取消注册。

如果问题仍然存在,请回复您编写的完整源代码以及您为此应用程序获取的logcat。