【问题标题】:How to get speed in android app using Location or accelerometer or some other way如何使用位置或加速度计或其他方式在 android 应用程序中获得速度
【发布时间】:2013-12-22 07:53:08
【问题描述】:

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

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

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

Drawing route on Google Maps using Google Maps Android API v2

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

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

【问题讨论】:

    标签: android performance gps location distance


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 首先感谢这个方法,我马上去试试。但仍然是速度问题是 location.getSpeed() 不起作用。所以基本上你建议我使用旧的位置 api 而不是新的 googla 播放服务更新位置 api?
    • getSpeed (developer.android.com/reference/android/location/…) 的文档说:Get the speed if it is available, in meters/second over ground。使用这种旧方式,您不必关心它是否可用。
    • 自过去 2 天以来我一直在处理速度问题,但不明白为什么它不起作用。我正在通过在车辆和脚上跑步在真实设备上对其进行测试。我还尝试了另一件事,我将计算行驶距离并将其除以时差以获得速度。但这样也行不通。
    • 为什么不使用location.distanceTo(Location)获取距离??
    • 如何获取不同的时间,比如 current_time = 0 new_time = system.currentTimeMills();然后在 cur_time = new_time;请解释...
    【解决方案2】:

    我在使用 Google Play Location API 的时候也遇到了这个问题,希望对你有帮助。

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

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

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

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

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

    我也尝试过使用活动识别来在计算时获得更好的速度准确度。

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

    【讨论】:

      【解决方案3】:

      在这个答案中,我将向您展示获得当前速度的两条主要途径。一种是使用位置服务 (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();
          }
      }
      

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

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

      【讨论】:

        【解决方案4】:
        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;
            }
        }
        

        【讨论】:

        • @P.K 如果当前位置有速度,则为米/秒,如果没有,则为米/毫秒。哪个聪明..真正聪明..
        猜你喜欢
        • 1970-01-01
        • 2012-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 2014-01-08
        • 1970-01-01
        相关资源
        最近更新 更多