2014-07-12 69 views
0

我有一個問題,我已經努力了幾個星期了。我旋轉我的手機 - Android傳感器值保持不變

我有一個使用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

可能性是:關閉應用程序之前,您可能沒有unregister()的sensorEventListener。因此,sensorManager在日誌中獲取onSensorChanged()事件。

所有你需要的是在申請關閉前unregisterListener()。您可以在onPause()活動方法中取消註冊。

如果問題仍然存在,請回復您編寫的完整源代碼以及您爲此應用程序獲得的logcat。

相關問題