2

コンパス データに従って回転する MapView を使用する Android 用のアプリケーションを作成しています。

問題は、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 に答える