我有一个服务类可以从GPS获取速度,地址,位置,经度和经度。我现有的应用程序获得了良好的结果,有一点容差。但我希望从location.getSpeed()
方法获得最准确的速度。例如,当我有80公里/小时的恒定速度时,它显示我76或77公里/小时。我怎样才能提高准确度?我想这样做没有任何误差。
我的GPS位置服务:
public class GPSLocationService extends Service {
private static final String TAG = "GPSLocationService";
private LocationManager locationManager;
private LocationListener gpsLocationListener;
private long lastGPStime;
private double lastLatitude;
private double lastLongitude;
private float lastSpeed;
private Address lastAddress;
private Location mLastLocation;
private float maxSpeed;
private final float metersSec_in_KMPH = 3.6f;
@SuppressLint("SimpleDateFormat")
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");
// other modules will call these public methonds
public String getTime() {
return timeFormat.format(new Date(lastGPStime));
}
public String getLocation(){
if(mLastLocation != null)
return mLastLocation.toString();
else
return "0";
}
public String getAddress(){
if(lastAddress != null)
return lastAddress.getAddressLine(0) + " " + lastAddress.getAddressLine(1) + " " + lastAddress.getAddressLine(2) + " " + lastAddress.getAddressLine(3);
else
return "0";
}
public float getSpeedFloat(){
if (lastSpeed < 1.0f) { return 0; }
float mph = lastSpeed * metersSec_in_KMPH;
return mph;
}
public Float getGpsStatus(){
if(mLastLocation != null)
return mLastLocation.getAccuracy();
else
return 0.0f;
}
// latitude ranges from 0.0 to 90.0
// In the US, latitude is always double-digits: 44.xxyyzz
// We'll keep six digits after the decimal point
public String getLat() {
String lValue = Double.toString(lastLatitude);
if (lValue.length() < 9)
return lValue;
return lValue.substring(0, 9);
} // latitude has max 2 digits before
// in the US, Longitude is always three digits: 123.xxyyzz
// We'll keep six digits after the decimal point (ITIS)
public String getLong() {
String lValue = Double.toString(lastLongitude);
if (lValue.length() < 10)
return lValue;
return lValue.substring(0, 10);
} // longitude has up to 3 digits
// speed is reported in meters/second
// speed needs three digits, and maybe three more past the decimal point:
// 145.608
public String getSpeed() {
if (lastSpeed < 1.0f) { return "000"; }
float mph = lastSpeed * metersSec_in_KMPH;
String lValue = Integer.toString((int) mph);
return lValue;
}
public String getMaxSpeed() {
if (maxSpeed < 1.0f) { return "0.0"; }
String lValue = Float.toString(maxSpeed * metersSec_in_KMPH);
if (lValue.length() < 7) {
return lValue;
} else
return lValue.substring(0, 7);
}
// setup this service to allow binding for access to public methods above.
// http://developer.android.com/guide/components/bound-services.html
private final IBinder mBinder = new GPSBinder();
public class GPSBinder extends Binder {
GPSLocationService getService() {
return GPSLocationService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// the usual 'Service' methods below
@Override
public void onCreate() {
super.onCreate();
// instantiate the inner class
gpsLocationListener = new GPSLocationListener();
// get the system manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// and demand Speed values
Criteria criteria = new Criteria();
criteria.setSpeedRequired(true);
locationManager.requestLocationUpdates(
locationManager.getBestProvider(criteria, false), 250,
5, gpsLocationListener);
Toast toast = Toast.makeText(GPSLocationService.this, "GPS updates requested.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
public void onDestroy() {
super.onDestroy();
locationManager.removeUpdates(gpsLocationListener);
}
private class GPSLocationListener implements LocationListener,
GpsStatus.Listener {
boolean isGPSFix;
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (mLastLocation != null)
isGPSFix = (SystemClock.elapsedRealtime() - lastGPStime) < 3000;
if (isGPSFix) { // A fix has been acquired.
Toast toast = Toast.makeText(GPSLocationService.this, "GPS has a fix.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
} else { // The fix has been lost.
Toast toast = Toast.makeText(GPSLocationService.this, "GPS DOES NOT have a fix.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
Toast toast = Toast.makeText(GPSLocationService.this, "GPS got first fix.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
isGPSFix = true;
break;
}
}
@Override
public void onLocationChanged(Location location) {
mLastLocation = location;
try {
lastAddress = getAddressForLocation(Main.context, location);
} catch (IOException e) {
Log.i("EXCEPTION", "Exception on Address");
e.printStackTrace();
}
lastGPStime = location.getTime();
lastLatitude = location.getLatitude();
lastLongitude = location.getLongitude();
lastSpeed = location.getSpeed();
if (lastSpeed > maxSpeed) {
maxSpeed = lastSpeed;
}
Log.i(TAG, "GPS update received.");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
String statusDescription = "unknown";
switch (status) {
case LocationProvider.OUT_OF_SERVICE:
statusDescription = "OUT_OF_SERVICE";
break;
case LocationProvider.AVAILABLE:
statusDescription = "AVAILABLE";
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
statusDescription = "TEMPORARILY_UNAVAILABLE";
break;
}
Toast toast = Toast.makeText(GPSLocationService.this, TAG + " GPS provider status changed to "
+ statusDescription + "and the last speed was: " + getSpeed() , Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
public void onProviderEnabled(String provider) {
Toast toast = Toast.makeText(GPSLocationService.this, "GPS provider enabled.", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
public void onProviderDisabled(String provider) {
Toast toast = Toast.makeText(GPSLocationService.this, "GPS provider disabled?", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
public void zeroMaxSpeed() {
maxSpeed = 0.0f;
}
public Address getAddressForLocation(Context context, Location location) throws IOException {
if (location == null) {
return null;
}
double latitude = location.getLatitude();
double longitude = location.getLongitude();
int maxResults = 1;
Geocoder gc = new Geocoder(context, Locale.getDefault());
List<Address> addresses = gc.getFromLocation(latitude, longitude, maxResults);
return addresses.get(0);
}
}
我在我的Main类中使用此服务的方法:
public class Main extends Activity {
private GPSLocationService gpsService;
private ServiceConnection gpsSvcConn;
private boolean isGPSserviceBound;
private static final String TAG = "FullScreenSpeed";
private Thread updateThread;
private Handler handler = new Handler();
private TextView address;
private TextView lat;
private TextView longi;
private TextView velocity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
address = (TextView) findViewById(R.id.address);
lat = (TextView) findViewById(R.id.latitude);
longi = (TextView) findViewById(R.id.longitude);
velocity = (TextView) findViewById(R.id.velocity);
updateThread = new Thread() {
public void run() {
if (isGPSserviceBound) {
speed = gpsService.getSpeed();
latitude = gpsService.getLat();
longitude = gpsService.getLong();
address.setText("Address: " + gpsService.getAddress());
lat.setText("Latitude: " + latitude);
longi.setText("Longitude: " + longitude);
velocity.setText("Velocity: " + speed + " Km/h");
if(i == 10){
i=0;
}
else{
arrayVelocity[i] = speed;
arrayLatitude[i] = latitude;
arrayLongitude[i] = longitude;
Log.i("HIZ","arrayVelocity[" + i + "] = " + speed);
Log.i("HIZ","arrayLatitude[" + i + "] = " + latitude);
Log.i("HIZ","arrayLongitude[" + i + "] = " + longitude);
i++;
}
} // GPS service isn't bound, can't do anything
handler.postDelayed(this, 14000); // wait a while
}
};
}
private void startGPSService() {
startService(new Intent(this, GPSLocationService.class));
gpsSvcConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
GPSBinder gpsBinder = (GPSBinder) binder;
gpsService = gpsBinder.getService();
isGPSserviceBound = true;
Toast toast = Toast.makeText(Main.this, "GPS service bound", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
isGPSserviceBound = false;
Toast toast = Toast.makeText(Main.this, "GPS service came unbound?", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
};
Intent intent = new Intent(this, GPSLocationService.class);
bindService(intent, gpsSvcConn, Context.BIND_AUTO_CREATE);
Log.i(TAG, "started gps service");
Toast toast = Toast.makeText(Main.this, "Started to bind to GPS service", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
protected void onResume() {
super.onResume();
handler.postDelayed(updateThread, 0);
Toast toast = Toast.makeText(Main.this, "MainActivity resumed", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
@Override
protected void onStop() {
super.onStop();
Toast toast = Toast.makeText(Main.this, "MainActivity stopped", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}