2014-07-12 148 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。

相关问题