2

我正在为 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);
            }
        }
    }
}

}

4

2 回答 2

0

一种替代方法是使用 gps 的方位而不是指南针。当然,这只有在您的用户正在移动并且是我对自行车应用程序所做的事情时才有效。如果您的用户没有移动,那么可能会获得 gps 修复,然后将其关闭并返回指南针。

于 2012-11-25T16:27:21.253 回答
0

好吧,我一直在研究这个,现在我注意到如果我使用已弃用的方向传感器而不是 API 推荐的加速度计和磁场传感器组合,我的应用程序运行良好且流畅。

所以现在的问题是为什么不推荐使用的方法比最新的方法效果更好?难道我做错了什么?

于 2012-11-27T16:13:17.710 回答