我正在为 Android 制作一个应用程序,它使用根据指南针数据旋转的 MapView。
问题是当 GPS 传感器工作时(定位我的位置并将其转换为 MapView),指南针数据会受到太多干扰。如果我把它关掉,指南针又能正常工作了。
我正在使用低通滤波器,但干扰大于 90º,所以它不起作用。
有什么解决办法吗?
这是我的 GPS 类代码:
public class LocationController implements LocationListener, GpsStatus.Listener {
private static final String TAG = "LOOKAROUND_LOCATION";
private LocationManager mService;
private LocationProvider mProvider;
private GpsStatus mStatus;
private ArrayList<LocationActivity> mLocationActivities = new ArrayList<LocationActivity>();
boolean mStarted;
private Location mLastLocation;
private static LocationController sInstance;
public static LocationController getInstance(Context context) {
if(sInstance == null){
sInstance = new LocationController(context);
}
return sInstance;
}
public void addLocationActivity(LocationActivity activity) {
mLocationActivities.add(activity);
}
public LocationController(Context context){
mService = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
mProvider = mService.getProvider(LocationManager.GPS_PROVIDER);
if (mProvider == null) {
Log.e(TAG, "Unable to get GPS_PROVIDER");
}
mService.addGpsStatusListener(this);
}
public void gpsStart() {
if (!mStarted) {
mService.requestLocationUpdates(mProvider.getName(), 1000, 0.0f, this);
mStarted = true;
}
for (LocationActivity activity : mLocationActivities) {
activity.gpsStart();
}
}
public void gpsStop() {
if (mStarted) {
mService.removeUpdates(this);
mStarted = false;
}
for (LocationActivity activity : mLocationActivities) {
activity.gpsStop();
}
}
public void onLocationChanged(Location location) {
mLastLocation = location;
for (LocationActivity activity : mLocationActivities) {
activity.onLocationChanged(location);
}
}
public void onProviderDisabled(String provider) {
for (LocationActivity activity : mLocationActivities) {
activity.onProviderDisabled(provider);
}
}
public void onProviderEnabled(String provider) {
for (LocationActivity activity : mLocationActivities) {
activity.onProviderEnabled(provider);
}
}
public void onStatusChanged(String provider, int status, Bundle extras) {
for (LocationActivity activity : mLocationActivities) {
activity.onStatusChanged(provider, status, extras);
}
}
public void onGpsStatusChanged(int event) {
mStatus = mService.getGpsStatus(mStatus);
for (LocationActivity activity : mLocationActivities) {
activity.onGpsStatusChanged(event, mStatus);
}
}
public void shutdownGps(){
mService.removeGpsStatusListener(this);
mService.removeUpdates(this);
}
public float getAccuracy(){
float acc = -1;
if(mLastLocation != null){
acc = mLastLocation.getAccuracy();
}
return acc;
}
public float getDeclination(){
float declination = 0;
if (mLastLocation != null) {
GeomagneticField geoField = new GeomagneticField(
(float) mLastLocation.getLatitude(),
(float) mLastLocation.getLongitude(),
(float) mLastLocation.getAltitude(),
mLastLocation.getTime());
declination = geoField.getDeclination();
}
return declination;
}
}
这是 Orientation 类代码:
public class OrientationController implements SensorEventListener{
private static final String TAG = "LOOKAROUND_ORIENTATION";
static final float ALPHA = 0.2f;
private SensorManager mSensorManager;
private ArrayList<OrientationActivity> mOrientationActivities = new ArrayList<OrientationActivity>();
Sensor accelerometer;
Sensor magnetometer;
float[] mGravity = null;
float[] mGeomagnetic = null;
float azimut;
private static OrientationController sInstance;
public static OrientationController getInstance(Context ctx) {
if (sInstance == null)
sInstance = new OrientationController(ctx);
return sInstance;
}
public void addOrientationActivity(OrientationActivity activity) {
mOrientationActivities.add(activity);
}
private OrientationController(Context ctx) {
mSensorManager = (SensorManager)ctx.getSystemService(Context.SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
private float[] lowPass( float[] input, float[] output ) {
if ( output == null ) return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + ALPHA * (input[i] - output[i]);
}
return output;
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = lowPass(event.values, mGravity);
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = lowPass(event.values, mGeomagnetic);
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
azimut = orientation[0];
float degAzimut = (float)Math.toDegrees(azimut);
for(OrientationActivity orientationActivity : mOrientationActivities){
orientationActivity.onOrientationChanged(degAzimut);
}
}
}
}
}