【问题标题】:How to calculate distance every 15 sec with using GPS heavy accuracy如何使用 GPS 高精度计算每 15 秒的距离
【发布时间】:2017-07-25 23:35:09
【问题描述】:

我可以通过 Map.getMyLocation().getLatitude()locationManagermGoogleApiClient 等 3 种方式获取 GPS 位置。 但这些对我每 15 秒计算一次距离没有帮助。 问题是位置纬度和经度不准确,即我使用这些方式距离计算步行 1-2 米。计算距离为 400 m-600 米有时也显示 1 公里GPS 位置从 20 米到 600 米不等。 请更好地了解如何通过在 android 中每 15 秒计算一次距离来获得我的位置高度准确度。

这是我的代码

//get current location
try {
    locationManager = (LocationManager) getApplicationContext()
            .getSystemService(LOCATION_SERVICE);

    // getting GPS status
    isGPSEnabled = locationManager
            .isProviderEnabled(LocationManager.GPS_PROVIDER);

    // getting network status
    isNetworkEnabled = locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    if (!isGPSEnabled && !isNetworkEnabled) {
        // no network provider is enabled
    } else {
        canGetLocation = true;
        // First get location from Network Provider
        if (isNetworkEnabled) {
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

            Log.d("Network", "Network");
            if (locationManager != null) {

                location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    old_latitude = location.getLatitude();
                    old_longitude = location.getLongitude();
                }
            }
        }
        // if GPS Enabled get lat/long using GPS Services
        if (isGPSEnabled) {
            if (location == null) {
                locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    if (location != null) {
                        old_latitude = location.getLatitude();
                        old_longitude = location.getLongitude();

                        Log.d("GPS Enabled", "GPS Enabled");
                    }
                }
            }
        }

    }
    //  Toast.makeText(this, "Current location"+current_latitude+","+current_longitude , Toast.LENGTH_LONG).show();
} catch (Exception e) {
    e.printStackTrace();
}

       /* GPSTracker gpsTracker = new GPSTracker(Activity_Map_Advance_Tracking.this);

        if (gpsTracker.getIsGPSTrackingEnabled()) {
            old_latitude=gpsTracker.latitude;
           old_longitude=gpsTracker.longitude;
        }*/
old_latitude = mMap.getMyLocation().getLatitude();
old_longitude = mMap.getMyLocation().getLongitude();

if (trip_status.equals("trip"))
    ha.postDelayed(new Runnable() {

        @Override
        public void run() {


            //get current location
            try {
                locationManager = (LocationManager) getApplicationContext()
                        .getSystemService(LOCATION_SERVICE);

                // getting GPS status
                isGPSEnabled = locationManager
                        .isProviderEnabled(LocationManager.GPS_PROVIDER);

                // getting network status
                isNetworkEnabled = locationManager
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

                if (!isGPSEnabled && !isNetworkEnabled) {
                    // no network provider is enabled
                } else {
                    canGetLocation = true;
                    // First get location from Network Provider
                    if (isNetworkEnabled) {
                        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

                        Log.d("Network", "Network");
                        if (locationManager != null) {

                            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                            if (location != null) {
                                new_latitude = location.getLatitude();
                                new_longitude = location.getLongitude();
                            }
                        }
                    }
                    // if GPS Enabled get lat/long using GPS Services
                    if (isGPSEnabled) {
                        if (location == null) {
                            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);


                            if (locationManager != null) {
                                location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                                if (location != null) {
                                    new_latitude = location.getLatitude();
                                    new_longitude = location.getLongitude();

                                    Log.d("GPS Enabled", "GPS Enabled");
                                }
                            }
                        }
                    }

                }
                //  Toast.makeText(this, "Current location"+current_latitude+","+current_longitude , Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
            // check if GPS enabled
               /* GPSTracker gpsTracker = new GPSTracker(Activity_Map_Advance_Tracking.this);

                if (gpsTracker.getIsGPSTrackingEnabled()) {
                    new_latitude = gpsTracker.latitude;
                    new_longitude =gpsTracker.longitude;
                }*/
            new_latitude = mMap.getMyLocation().getLatitude();
            new_longitude = mMap.getMyLocation().getLongitude();


            double GPS_jump = 0.000100;

            if (Math.abs(old_latitude - new_latitude) < GPS_jump && Math.abs(old_longitude - new_longitude) < GPS_jump) {
                waiting_sec = waiting_sec + 15;
                if (waiting_sec >= (waiting_time * 60)) {
                    if (wait == 0) {
                        waitng_charge = (waiting_amnt_per_sec * waiting_sec) + waitng_charge;
                        wait = 15;
                        //waiting_sec=0;
                    } else {
                        waitng_charge = (waiting_amnt_per_sec * wait) + waitng_charge;
                    }
                }

                // total_distance=meterDistanceBetweenPoints(13.020876, 80.222541,13.021301, 80.222881)+total_distance;
                // client_info.setText("TOTAL DISTANCE:"+total_distance/1000);
                System.out.println("vehicle not move" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude));
                Toast.makeText(Activity_Map_Advance_Tracking.this, "vehicle not move" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();


                // assuming doubles are equals
            } else {

                System.out.println("vehicle moved" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude));
                if ((waiting_sec) >= (waiting_time * 60)) {
                    waitng_charge = waiting_amnt_per_sec + waitng_charge;
                }
                total_distance = meterDistanceBetweenPoints(old_latitude, old_longitude, new_latitude, new_longitude) + total_distance;
                waiting_sec = 0;
                wait = 0;

                Toast.makeText(Activity_Map_Advance_Tracking.this, "vehicle moved" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
                Toast.makeText(Activity_Map_Advance_Tracking.this, "****TOTAL DISTANCE*****->" + total_distance, Toast.LENGTH_LONG).show();
                client_info.setText("TOTAL DISTANCE:" + total_distance);
            }


            delay_sec = delay_sec + 15;
            System.out.println("After " + delay_sec + " sec \n waiting sec" + waiting_sec + " sec\n waitng charge" + waitng_charge + "rs \n currunt lat and lng" + new_latitude + " , " + new_longitude + "" +
                    "\n___old lat lng" + old_latitude + " , " + old_longitude);


            Toast.makeText(Activity_Map_Advance_Tracking.this, "After " + delay_sec + " sec \n waiting sec" + waiting_sec + " sec\n waitng charge" + waitng_charge + "rs \n currunt lat and lng" + new_latitude + " , " + new_longitude + "" +
                    "\n___old lat lng" + old_latitude + " , " + old_longitude + ", \ntotal distance: " + total_distance, Toast.LENGTH_LONG).show();


            old_latitude = new_latitude;
            old_longitude = new_longitude;

            //call function
            ha.postDelayed(this, 15000);
        }
    }, 15000);

这是我的距离计算方法 但是这个方法没有问题

 private float meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
    /*Location locationA = new Location("point A");

    locationA.setLatitude(lat_a);
    locationA.setLongitude(lng_a);

    Location locationB = new Location("point B");

    locationB.setLatitude(lat_b);
    locationB.setLongitude(lng_b);

    float distance = locationA.distanceTo(locationB);*/
    double earthRadius = 6371000; //meters
    double dLat = Math.toRadians(lat_b - lat_a);
    double dLng = Math.toRadians(lng_b - lng_a);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(Math.toRadians(lat_a)) * Math.cos(Math.toRadians(lat_b)) *
                    Math.sin(dLng / 2) * Math.sin(dLng / 2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    float dist = (float) (earthRadius * c);


    System.out.println("**********this is distance calculation**********" + dist);
    return dist;
}

【问题讨论】:

  • 你为什么要使用 Handler 在 15 秒后获取位置更新?!您可以通过 LocationManager 和 FusedLocationApi 在特定时间或距离后获取位置更新
  • @tahsinRupam 我也尝试使用 LocationManager 或 FusedLocationApi 使用 mLLocationRequest.setInterval(INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL);但没有用。问题是位置重跳
  • 它没有用?您面临哪些问题?
  • 位置偏差,例如 200 m 到 600 m。 GPS定位跳转
  • 在不良接收条件下这是很正常的。即使在最佳条件下,10m 也是您所希望的最佳值。

标签: android google-maps distance android-gps gpsd


【解决方案1】:

在一个答案中,代码:

distanceInMeters += previousLocation.distanceTo(location);

很好,但我建议 - 除非有人发现它有问题,否则只需使用:

locationManager.requestLocationUpdates(provider, 0, DISTANCE, mylistener); 

并累积 DISTANCE(前提是它是一个相对较小的 DISTANCE)。抱歉,我不能把它放在 cmets 中,因为它们删除了很多点。

编辑:但 distanceInMeters += previousLocation.distanceTo(location) 比我上面建议的更准确。

【讨论】:

    【解决方案2】:

    您可以使用 requestLocation update 开始获取位置更新:

    mylistener = new MyLocationListener();
    locationManager.requestLocationUpdates(provider, 150000, 1, mylistener);
    

    在这里,您将在每 15 秒和 1 米位置更改后获得更新:

    当 locationmanager 获取位置更新时,它会调用 onLocationChanged() 方法。您将在那里获得更新的位置。

    private class MyLocationListener implements LocationListener {
    
        @Override
        public void onLocationChanged(Location location) {
        }
             //Do your code with this updated location
    }
    

    您可以设置标准位置收集。如果您想获得准确的位置,我建议您仅使用 GPS_PROVIDER。请记住,GPS 在屋内无法正常工作。

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_HIGH);
        provider = locationManager.getBestProvider(criteria, true);
        previouslocation = locationManager.getLastKnownLocation(provider);
    

    全局声明 -

     float distanceInMeters = 0; 
    

    在onLocationChanged()中添加距离:

    public void onLocationChanged(Location location) {
          distanceInMeters += previousLocation.distanceTo(location);  
          Toast.makeText(YourActivity.this, "Distance" + distanceInMeters,Toast.LENGTH_SHORT).show();    // Showing the distance in meter
          previousLocation = location;
       }
    

    注意:我已将第一个位置值更改为 previousLocation 以避免混淆。

    【讨论】:

    • 任何时间的伙伴 ;)
    • @tasinRupan 这对我不起作用。同样的问题,如位置跳转。像 .012 一样跳到 .02
    • 你的距离是公里吗?实际距离的位移量是多少?甚至 GPS 也可能相差 20 英尺左右。查看这篇文章 - developerlife.com/2010/10/20/gps
    • @tasinRupan bro 我使用上面的代码创建样本距离计算但同样的问题请检查stackoverflow.com/a/42625593/7399521谢谢
    • 从 onLocationChanged() 中删除这一行: location = locationManager.getLastKnownLocation(provider);并将更新后的代码添加到您的问题中(编辑上一个)
    【解决方案3】:

    请检查一下 使用喜欢

       criteria.setPowerRequirement(Criteria.POWER_HIGH);
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
    LocationManager locationManager;
    Criteria criteria;
    String provider;
    Location location;
    double old_latitude; // latitude
    double old_longitude; // longitude
    TextView distance;
    double new_latitude; // latitude
    double new_longitude; // longitude
    float total_distance = 0.0f;
    String details;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        distance = (TextView) findViewById(R.id.distance);
    
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setPowerRequirement(Criteria.POWER_HIGH);
        provider = locationManager.getBestProvider(criteria, true);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        location = locationManager.getLastKnownLocation(provider);
    
        try {
            old_latitude = location.getLatitude();
            old_longitude = location.getLongitude();
        } catch (Exception e) {
    
        }
    
        locationManager.requestLocationUpdates(provider, 15000, 1, new LocationListener() {
    
    
            @Override
            public void onLocationChanged(Location location) {
                if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    return;
                }
                location = locationManager.getLastKnownLocation(provider);
                new_latitude = location.getLatitude();
                new_longitude = location.getLongitude();
    
                total_distance = meterDistanceBetweenPoints(old_latitude, old_longitude, new_latitude, new_longitude) + total_distance;
    
                if (details == null) {
                    details = "current location:" + new_latitude + ", " + new_longitude;
                    details = details + "\n" + "old location:" + old_latitude + ", " + old_longitude;
                    details = details + "\n" + "\n" + "total distance:" + total_distance + " m";
                    details = details + "\n" + "----------------------------------------------" + "\n";
                } else {
    
                    details = details + "\n" + "current location:" + new_latitude + ", " + new_longitude;
                    details = details + "\n" + "old location:" + old_latitude + ", " + old_longitude;
                    details = details + "\n" + "\n" + "total distance:" + total_distance + " m";
                    details = details + "\n" + "----------------------------------------------" + "\n";
                }
    
                distance.setText(details);
    
                old_latitude = new_latitude;
                old_longitude = new_longitude;
    
                System.out.println("**********this is LocationChanged**********" + 15000);
                Toast.makeText(MainActivity.this, "current location" + new_latitude + new_longitude, Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "old location" + old_latitude + old_longitude, Toast.LENGTH_LONG).show();
                Toast.makeText(MainActivity.this, "LocationChanged" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
    
            }
    
            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
                System.out.println("**********this is StatusChanged**********" + 15000);
                Toast.makeText(MainActivity.this, "StatusChanged" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
    
            }
    
            @Override
            public void onProviderEnabled(String s) {
                System.out.println("**********this is ProviderEnabled**********" + 15000);
                Toast.makeText(MainActivity.this, "ProviderDisabled" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
    
            }
    
            @Override
            public void onProviderDisabled(String s) {
                System.out.println("**********this is ProviderDisabled**********" + 15000);
                Toast.makeText(MainActivity.this, "ProviderDisabled" + Math.abs((float) old_latitude - (float) new_latitude) + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
    
            }
        });
    
    
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    private float meterDistanceBetweenPoints(double lat_a, double lng_a, double lat_b, double lng_b) {
        double earthRadius = 6371000; //meters
        double dLat = Math.toRadians(lat_b - lat_a);
        double dLng = Math.toRadians(lng_b - lng_a);
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(Math.toRadians(lat_a)) * Math.cos(Math.toRadians(lat_b)) *
                        Math.sin(dLng / 2) * Math.sin(dLng / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        float dist = (float) (earthRadius * c);
        Toast.makeText(MainActivity.this, "calculated distance" + dist + "," + Math.abs((float) old_longitude - (float) new_longitude), Toast.LENGTH_LONG).show();
        System.out.println("**********this is distance calculation**********" + dist);
        return dist;
    }}
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.rmadeandroid.lcation_change_listioner.MainActivity">
    
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    </android.support.design.widget.AppBarLayout>
    
    <include layout="@layout/content_main" />
    
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email" /</android.support.design.widget.CoordinatorLayout>
    

    content_main.xml

    <?xml version="1.0" encoding="utf-8"?><ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.rmadeandroid.lcation_change_listioner.MainActivity"
    tools:showIn="@layout/activity_main"><RelativeLayout
    android:id="@+id/content_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"><TextView
        android:id="@+id/distance"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="device not move" /></RelativeLayout></ScrollView>
    

    清单中的权限

     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

    输出

    【讨论】:

    • 在运行您的应用程序之前启用您的设备 GPS LOCATION
    【解决方案4】:

    正如 cmets 部分中的某个人所发布的,使用 LocationManager /FusedLocationApi。你可以额外做的是:

    1. 即使您每 15 秒需要一次位置,也可以以较小的间隔或连续获取位置,然后计算。这会给设备的电池带来压力。
    2. 如果您获得的新位置与上一个位置相距很远,请忽略它。有些设备可能会返回错误的值(有一个现在可以工作的 Nexus5,下一秒显示 4-5 公里)。
    3. 如果电池会成为问题,请将时间间隔设置为 15 秒,可能使用 PRIORITY_BALANCED_POWER_ACCURACY,但请确保您有备用方案。如果两个位置之间的距离太大或读数的准确性不好,请忽略它/请求另一个位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多