如何从位置获得最准确的速度

时间:2013-12-30 12:30:43

标签: android android-location

我有一个服务类可以从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();

    }

}

1 个答案:

答案 0 :(得分:0)

检查完这些链接Link1Link2后,我意识到我的速度是正确的,我测试我的应用程序的汽车的速度表没有显示正确的值。他们总是显示出真正的汽车速度。因此,我的应用程序的价值优于汽车的速度表。