如何使用位置或加速度计或其他方式在 android 应用程序中获得速度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20398898/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:47:30  来源:igfitidea点击:

How to get speed in android app using Location or accelerometer or some other way

androidperformancegpslocationdistance

提问by Scorpion

I am working on app and try to get the speed and distance travelled by the user. I have used Google Play services location class to get the speed but it always returns me 0.0 value and not at all reliable. I wan accurate speed and distance travelled at real time.

我正在开发应用程序并尝试获取用户行驶的速度和距离。我已经使用 Google Play 服务位置类来获得速度,但它总是返回 0.0 值并且一点也不可靠。我想要实时行驶的准确速度和距离。

I have installed GPS Speedometer app on my device and its so perfect that even if i am walking then it gives me the speed. I want to get the same thing. I am confused in how to get speed, using location or using accelerometer or is there any other way to do it?

我已经在我的设备上安装了 GPS 车速表应用程序,它非常完美,即使我在走路,它也会给我速度。我想得到同样的东西。我对如何获得速度、使用位置或使用加速度计感到困惑,或者还有其他方法可以做到吗?

My code is available on this link :-

我的代码可在此链接上找到:-

Drawing route on Google Maps using Google Maps Android API v2

使用 Google Maps Android API v2 在 Google Maps 上绘制路线

I am developing pure location based app which includes map, speed and other related things which are related to Locations.

我正在开发纯基于位置的应用程序,其中包括地图、速度和其他与位置相关的相关内容。

If anyone has any idea please kindly help me on resolving the issue of Speed and Distance.

如果有人有任何想法,请帮助我解决速度和距离的问题。

回答by gahfy

I had to deal with same problem, what you can do is to use Location Strategiescode.

我不得不处理同样的问题,你可以做的是使用Location Strategies代码。

Then, on each update of location, you save the time of the current update. So, you will have the previous and current location, and time of update.

然后,在每次更新位置时,您都会保存当前更新的时间。因此,您将拥有以前和当前的位置以及更新时间。

Then you calculate the distance in meters between those two locations (the old and new one)

然后计算这两个位置(旧的和新的)之间的距离(以米为单位)

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

So, then you have the distance and the time difference, I think it wouldn't be a big deal to get the speed.

所以,那么你有距离和时差,我认为获得速度没什么大不了的。

回答by black1011

I also encountered this problem when I was using Google Play Location API, I hope this can help.

我在使用 Google Play Location API 的时候也遇到过这个问题,希望可以帮到你。

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

它返回 0,因为您的设备无法锁定 GPS,或者无法连接到 GPS。

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

我尝试使用较旧的 lenovo 设备来获得速度,但它返回 0,因为它无法锁定 gps。

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

我尝试使用三星 Galaxy nexus,它返回了我的速度(有更好的 GPS 传感器)。

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.

您手机中的 GPS 传感器可能不好,或者您所在的区域 GPS 信号较弱,例如房屋或建筑物内。

What I did was compute for speed if location.hasSpeed is false and use location.getSpeed if location.hasSpeed is true.

如果 location.hasSpeed 为 false,我所做的是计算速度,如果 location.hasSpeed 为 true,则使用 location.getSpeed。

I also tried to use the activity recognition to have a better accuracy of speed when computing.

我还尝试使用活动识别来提高计算速度的准确性。

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

回答by Ashana.Hymanol

in this answer im gonna show you two main path to get current speed.one is by using location service (location.getSpeed()) and other one is old school manually calculate speed version.

在这个答案中,我将向您展示获取当前速度的两种主要途径。一种是使用位置服务(location.getSpeed()),另一种是老派手动计算速度版本。

first define three main global variables

首先定义三个主要的全局变量

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

now move on to your onLocationChanngedmethod and inside it call to this method,

现在转到您的onLocationChanged方法并在其中调用此方法,

getspeed(location);

now lets implement getSpeedmethod

现在让我们实现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 we are done with it, and now implement calculationBydistancemethod

好的,我们完成了,现在实现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;
}

in here else part the speed will comes in m/miliseconds you can convert it to seconds...and we are done

在其他部分,速度将以米/毫秒为单位,您可以将其转换为秒......我们就完成了

回答by user2746732

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