Как получить скорость в android app с помощью местоположения или акселерометра или каким-либо другим способом

Я работаю над приложением и пытаюсь получить скорость и расстояние, пройденное пользователем. Я использовал класс местоположения служб Google Play, чтобы получить скорость, но он всегда возвращает мне значение 0.0 и совсем не надежный. Я хочу точную скорость и расстояние, пройденное в режиме реального времени.

Я установил приложение GPS спидометр на моем устройстве и его так идеально, что даже если я иду, то это дает мне скорость. Я хочу получить то же самое. Я запутался в том, как получить скорость, используя местоположение или использование акселерометра или есть какой-либо другой способ сделать это?

мой код доступен по этой ссылке :-

рисование маршрута на картах Google с помощью Google Maps Android API v2

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

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

4 ответов


мне приходилось сталкиваться с той же проблемой, что вы можете сделать, это использовать Стратегии Расположения код.

затем при каждом обновлении местоположения вы сохраняете время текущего обновления. Таким образом, у вас будет предыдущее и текущее местоположение и время обновления.

затем вы вычисляете расстояние в метрах между этими двумя местоположениями (старым и новым)

private static long calculateDistance(double lat1, double lng1, double lat2, double lng2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lng2 - lng1);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(Math.toRadians(lat1))
            * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
            * Math.sin(dLon / 2);
    double c = 2 * Math.asin(Math.sqrt(a));
    long distanceInMeters = Math.round(6371000 * c);
    return distanceInMeters;
}

Итак, тогда у вас есть расстояние и разница во времени, я думаю, что это не будет большим интернет, чтобы получить скорость.


Я также столкнулся с этой проблемой, когда я использовал Google Play Location API, я надеюсь, что это может помочь.

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

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

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

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

то, что я сделал, это вычислить скорость, если местоположение.hasSpeed является ложным и использует местоположение.getSpeed если расположение.hasSpeed это правда.

Я также попытался использовать распознавание активности, чтобы иметь лучшую точность скорости при вычислениях.

    //Computation for speed
    cur_time = System.currentTimeMillis() / 1000L;
    if (location.hasSpeed()) {
        loc_Speed = location.getSpeed();
        //counter goes back to 0
        count_OnFoot = 0;
        Toast.makeText(getBaseContext(), "has speed", Toast.LENGTH_SHORT).show();
    } else {
        float[] result = new float[1];
        location.distanceBetween(prev_latitude, prev_longitude,
                loc_Latitude, loc_Longitude,
                result);
        float loc_distance = result[0];
        //speed if location.getSpeed is null
        loc_Speed = loc_distance/(cur_time - prev_time);

        //if activity type is on foot
        //estimate AVE_RUNNING_SPEED = 3m/s
        if (act_ActivityType.equals(ActivityRecognitionService.ACT_ON_FOOT) && loc_Speed > AVE_RUNNING_SPEED) {
            count_OnFoot++;
            if (count_OnFoot < 2) {
                Toast.makeText(getBaseContext(), "on foot and 1st > 3m/s", Toast.LENGTH_SHORT).show();
                /*
                 * Since the speed is more than
                 * the average running speed,we will
                 * assume that its not a correct value
                 * and a fault that it detected a very far signal from the previous one.
                 * (This happens sometimes)
                 * We will assign the previous speed
                 * as its current speed.
                 */
                loc_Speed = prev_Speed;
            } else {
                Toast.makeText(getBaseContext(), "on foot and TWICE > 3m/s in a row", Toast.LENGTH_SHORT).show();
                /*
                 * Do Nothing
                 * loc_Speed is equals the computed speed 
                 * if it happens twice or more in a row.
                 * We will assume that its running fast.
                 */
            }
        }else {

            count_OnFoot = 0;
        }
    }
    prev_Speed = loc_Speed;
    /*
     * If more than 60% sure that its still.
     * 
     * Let your speed and direction be 0
     * latitude and longitude should not change
     */
    if (act_ActivityType.equals(ActivityRecognitionService.ACT_STILL)) {
        loc_Speed = 0;
        loc_Direction = 0;
        if (prev_latitude != 0 && prev_longitude != 0) {
            loc_Latitude = prev_latitude;
            loc_Longitude = prev_longitude;
        }
    }

    prev_time = cur_time;
    prev_latitude = loc_Latitude;
    prev_longitude = loc_Longitude;

    //Note: My activity type will return on foot or still if its more than 60% sure
    //otherwise null.

в этом ответе я покажу вам два основных пути, чтобы получить текущую скорость.один-с помощью службы определения местоположения (location.getSpeed ()), а другой-старая школа вручную вычисляет версию скорости.

сначала определите три основные глобальные переменные

double curTime= 0;
double oldLat = 0.0;
double oldLon = 0.0;

теперь перейдем к вашей onLocationChannged метод и внутри него вызовите этот метод,

getspeed(location);

теперь давайте реализовывать getSpeed метод

private void getspeed(Location location){
    double newTime= System.currentTimeMillis();
    double newLat = location.getLatitude();
    double newLon = location.getLongitude();
    if(location.hasSpeed()){
        float speed = location.getSpeed();
        Toast.makeText(getApplication(),"SPEED : "+String.valueOf(speed)+"m/s",Toast.LENGTH_SHORT).show();
    } else {
        double distance = calculationBydistance(newLat,newLon,oldLat,oldLon);
        double timeDifferent = newTime - curTime;
        double speed = distance/timeDifferent;
        curTime = newTime;
        oldLat = newLat;
        oldLon = newLon;
        Toast.makeText(getApplication(),"SPEED 2 : "+String.valueOf(speed)+"m/s",Toast.LENGTH_SHORT).show();
    }
}

ok мы закончили с ним и теперь реализуем calculationBydistance метод

public double calculationBydistance(double lat1, double lon1, double lat2, double lon2){
    double radius = EARTH_RADIUS;
    double dLat = Math.toRadians(lat2-lat1);
    double dLon = Math.toRadians(lon2-lon1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                    Math.sin(dLon/2) * Math.sin(dLon/2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return radius * c;
}

здесь еще часть скорости будет приходит в М / миллисекунды, которые вы можете преобразовать в секунды...и мы закончили


public static double getSpeed(Location currentLocation, Location oldLocation)
{
    double newLat = currentLocation.getLatitude();
    double newLon = currentLocation.getLongitude();

    double oldLat = oldLocation.getLatitude();
    double oldLon = oldLocation.getLongitude();

    if(currentLocation.hasSpeed()){
        return currentLocation.getSpeed();
    } else {
        double radius = 6371000;
        double dLat = Math.toRadians(newLat-oldLat);
        double dLon = Math.toRadians(newLon-oldLon);
        double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(Math.toRadians(newLat)) * Math.cos(Math.toRadians(oldLat)) *
                        Math.sin(dLon/2) * Math.sin(dLon/2);
        double c = 2 * Math.asin(Math.sqrt(a));
        double distance =  Math.round(radius * c);

        double timeDifferent = currentLocation.getTime() - oldLocation.getTime();
        return distance/timeDifferent;
    }
}