我有一个问题,我已经挣扎了几个星期了。
我有一个使用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);
}
答案 0 :(得分:-1)
可能性可能是:在关闭应用程序之前,您可能没有unregister()
sensorEventListener。因此,sensorManager会在您的日志中收到onSensorChanged()
个事件。
在应用程序关闭之前,您只需要unregisterListener()
。您可以使用onPause()
活动方法取消注册。
如果问题仍然存在,请回复您编写的完整源代码以及您为此应用程序获取的logcat。