Почему getSpeed ​​() всегда возвращает 0 на android

Мне нужно получить скорость и заголовок из gps. Однако единственное число, которое я имеет от location.getSpeed(), равно 0 или иногда недоступно. мой код:

        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;
}

Я пытался сыграть в "Критерии" без успеха. Кто-нибудь есть идея, в чем проблема?

Ответы

Ответ 1

location.getSpeed ​​() возвращает только то, что было установлено с помощью location.setSpeed ​​(). Это значение, которое вы можете установить для объекта местоположения.

Чтобы вычислить скорость с помощью GPS, вам нужно сделать небольшую математику:

Speed = distance / time

Итак, вам нужно будет сделать:

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

Все преобразованы в ft/sec или, тем не менее, вы хотите показать скорость. Так я сделал это, когда сделал приложение для бегунов.

В частности, вам нужно будет рассчитать абсолютные расстояния:

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

Это может помочь создать новый класс TrackPoint или что-то еще, что сохраняет местоположение GPS и время, в которое он был взят внутри.

Ответ 2

Есть мой пользовательский LocationListener, используемый для получения скорости вручную и по местоположению, если есть скорость.

 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

На сферической планете расстояние должно быть рассчитано с помощью этих формул:

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 answer выглядит действительно хорошо, но это не очень полезно, если вы работаете с ед.

Здесь я сделал, чтобы вычислить скорость в метрах в секунду (м/с).

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() работает нормально. Вам не нужно делать математику, используя формулу расстояния. Он уже существует в ускоренном режиме, до тех пор, пока есть широта и долгота, скорость будет достигнута.

Ответ 6

(1) Я считаю, что вы можете использовать метод requestLocationUpdates(), а затем создать класс LocationListener с методом onLocationChange, установленным для отображения getSpeed(). Вот как я недавно видел это с помощью Location.getLatitude и Location.getLongitude, поэтому я считаю, что вы можете просто использовать getSpeed ​​() таким же образом, правильно?

(2) После простого чтения окна описания eclipse я вижу, что он точно говорит о том, что сказал предыдущий человек: "if hasSpeed ​​() является ложным, возвращается 0.0f".    Но, возможно, это поможет: http://www.ehow.com/how_5708473_convert-latitude-feet.html:)

Ответ 7

Я также столкнулся с этой проблемой раньше, Надеюсь, это поможет.

Он возвращает 0, потому что ваше устройство не может получить блокировку на GPS или не может подключиться к GPS.

Я попытался получить скорость с помощью старого устройства lenovo, и он возвращает 0, потому что он не может заблокировать gps.

Я попытался использовать галактическую галактику samsung, и она вернула мою скорость (имеет лучший GPS-датчик).

Датчик GPS в вашем телефоне может быть не очень хорошим, или вы находитесь в зоне с слабым сигналом GPS, например, внутри дома или здания.

Ответ 8

Я базово вычисляю мгновенную скорость, а затем использую метод setSpeed ​​(), чтобы добавить его в местоположение. Его довольно точно, потому что я сравнивал его внутри транспортного средства, где я мог проверить тахеометр.

private double calculateInstantaneousSpeed(Location location) {



    double insSpeed = 0;
    if (y1 == null && x1 <= -1) {
        //mark the location y1 at time x1
        y1 = location;
        x1 = duration.getDurationAsSeconds();


    } else {
         //mark the location y2 at time x2
        y2 = location;
        x2 = duration.getDurationAsSeconds();


        //calculate the slope of the curve (instantaneous speed)
        dy = y1.distanceTo(y2);
        dx = x2 - x1;

        insSpeed = dy / dx;

        y1 = y2;
        x1 = x2;

    }

    Singleton.getInstance().instantaneousSpeedSamples.add(insSpeed);
    //System.out.println("Instantaneous Speed m/s: "+insSpeed);
    return insSpeed;
}