我有一個問題,我已經努力了幾個星期了。我旋轉我的手機 - 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);
}