why getSpeed() always return 0 on android

Solution 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.

Solution 2:

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).

object : LocationListener() {
    var previousLocation: Location? = null

    override fun onLocationChanged(location: Location) {
        val speed = if (location.hasSpeed()) {
            location.speed
        } else {
            previousLocation?.let { lastLocation ->
                // Convert milliseconds to seconds
                val elapsedTimeInSeconds = (location.time - lastLocation.time) / 1_000.
                val distanceInMeters = lastLocation.distanceTo(location)
                // Speed in m/s
                distanceInMeters / elapsedTimeInSeconds
            } ?: 0.0
        }
        previousLocation = location

        /* There you have it, a speed value in m/s */
        functionThatUsesSpeedInMeterPerSecond(speed)

        . . .

    }

    . . .

}

Solution 3:

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) {

        }
    };