why getSpeed() always return 0 on android

匿名 (未验证) 提交于 2019-12-03 08:33:39

问题:

I need to get the speed and heading from the gps. However the only number i have from location.getSpeed() is 0 or sometimes not available. my code:

        String provider = initLocManager();     if (provider == null)         return false;     LocationListener locListener = new LocationListener() {         public void onLocationChanged(Location location) {             updateWithNewLocation(location, interval, startId);             Log.i(getString(R.string.logging_tag), "speed =" + location.getSpeed());         }          public void onProviderDisabled(String provider){             updateWithNewLocation(null, interval, startId);         }          public void onProviderEnabled(String provider) {}         public void onStatusChanged(String provider, int status, Bundle extras) {}     };      _locManager.requestLocationUpdates(provider, interval,  DEFAULT_GPS_MIN_DISTANCE, locListener);       private String initLocManager() {     String context = Context.LOCATION_SERVICE;     _locManager = (LocationManager) getSystemService(context);      Criteria criteria = new Criteria();     criteria.setAccuracy(Criteria.ACCURACY_FINE);     criteria.setAltitudeRequired(false);     criteria.setBearingRequired(true);     criteria.setSpeedRequired(true);     criteria.setCostAllowed(true);     //criteria.setPowerRequirement(Criteria.POWER_LOW);     String provider = _locManager.getBestProvider(criteria, true);      if (provider == null || provider.equals("")) {         displayGPSNotEnabledWarning(this);         return null;     }      return provider; } 

I tried to play the Criteria with but no success. Does anyone have an idea what is the problem?

回答1:

location.getSpeed() only returns what was set with location.setSpeed(). This is a value that you can set for a location object.

To calculate the speed using GPS, you'll have to do a little math:

Speed = distance / time 

So you would need to do:

(currentGPSPoint - lastGPSPoint) / (time between GPS points) 

All converted to ft/sec, or however you want to show the speed. This is how I did it when I made a runner app.

More specifically, you'll need to calculate for absolute distances:

(sqrt((currentGPSPointX - lastGPSPointX)^2) + (currentGPSPointY - lastGPSPointY)^2)) / (time between GPS points) 

It might help to make a new TrackPoint class or something, which keeps the GPS location and time it was taken inside.



回答2:

There is my custom LocationListener used to get speed manually and by location object if has speed.

 new LocationListener() {         private Location mLastLocation;          @Override         public void onLocationChanged(Location pCurrentLocation) {             //calcul manually speed             double speed = 0;             if (this.mLastLocation != null)                 speed = Math.sqrt(                         Math.pow(pCurrentLocation.getLongitude() - mLastLocation.getLongitude(), 2)                                 + Math.pow(pCurrentLocation.getLatitude() - mLastLocation.getLatitude(), 2)                 ) / (pCurrentLocation.getTime() - this.mLastLocation.getTime());             //if there is speed from location             if (pCurrentLocation.hasSpeed())                 //get location speed                 speed = pCurrentLocation.getSpeed();             this.mLastLocation = pCurrentLocation;             ////////////             //DO WHAT YOU WANT WITH speed VARIABLE             ////////////         }          @Override         public void onStatusChanged(String s, int i, Bundle bundle) {          }          @Override         public void onProviderEnabled(String s) {          }          @Override         public void onProviderDisabled(String s) {          }     }; 


回答3:

On a spherical planet distance should be calculated with these formulas :

private static Double distance(Location one, Location two) {        int R = 6371000;                Double dLat = toRad(two.getLatitude() - one.getLatitude());        Double dLon = toRad(two.getLongitude() - one.getLongitude());        Double lat1 = toRad(one.getLatitude());        Double lat2 = toRad(two.getLatitude());                 Double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)                + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);                Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));                Double d = R * c;        return d;    } private static double toRad(Double d) {        return d * Math.PI / 180;    } 


回答4:

Imbru's answer looks really good, but it is not very helpful if you are working with units.

Here's what I did to calculate the speed in meters per second (m/s).

new LocationListener() {     private Location lastLocation = null;     private double calculatedSpeed = 0;      @Override     public synchronized void onLocationChanged(Location location) {         if (lastLocation != null) {             double elapsedTime = (location.getTime() - lastLocation.getTime()) / 1_000; // Convert milliseconds to seconds             calculatedSpeed = lastLocation.distanceTo(location) / elapsedTime;         }         this.lastLocation = location;          double speed = location.hasSpeed() ? location.getSpeed() : calculatedSpeed;          /* There you have it, a speed value in m/s */          . . .      }      . . .  } 


回答5:

getspeed() works fine. You don't have to do the math using distance formula. It is already there in getspeed, As long as there are latitude and longitude, there will be a speed in getspeed.



回答6:

(1) I believe you can use the requestLocationUpdates() method and then create a LocationListener class with an onLocationChange method set to display getSpeed(). This is how i recently saw it done with Location.getLatitude and Location.getLongitude, so I believe you could just use getSpeed() the same way, correct?

(2) After just reading the eclipse description window, though, I see it says exactly what the previous person said: "if hasSpeed() is false, 0.0f is returned." But maybe this will help: http://www.ehow.com/how_5708473_convert-latitude-feet.html :)



回答7:

I also encountered this problem before, I hope this can help.

It returns 0 because your device cannot get a lock on the GPS, or cannot connect to the GPS.

I tried to get the speed using an older lenovo device and it returns 0 because it cannot lock on a gps.

I tried using a samsung galaxy nexus and it returned my speed(has a better GPS sensor).

The GPS sensor in your phone might not be good or you are in an area that has a weak GPS signal such as inside a house or building.



回答8:

I basicaslly calculate the instantaneous speed and then use the setSpeed() method to add it in the location. Its pretty accurate because I compared it inside a vehicle where I could check the tachymeter.

private double calculateInstantaneousSpeed(Location location) {        double insSpeed = 0;     if (y1 == null && x1 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!