Android实时计算行驶距离求助:distanceTo与distanceBetween选型及TextView展示
Android实时计算行驶距离实现指南
先理清distanceTo和distanceBetween的区别
不用纠结哪个是最优方案,两者底层逻辑完全一致(都是基于WGS84坐标系计算大圆直线距离),只是使用场景不同:
distanceTo(Location dest):是Location类的成员方法,用法更简洁——直接用当前Location对象调用,就能算出到目标Location的距离(单位米),适合手里已经有两个Location实例的场景。distanceBetween(double startLat, double startLng, double endLat, double endLng, float[] results):是Location类的静态方法,不需要创建Location对象,直接传入两组经纬度坐标,计算结果会存入你传入的float数组(第一个元素就是距离值),适合只有原始经纬度数据的场景。
实时计算行驶距离的完整实现步骤
1. 先搞定权限
在AndroidManifest.xml里添加必要权限:
<!-- 基础定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 后台定位权限(如果需要后台持续计算) --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Android 6.0以上必须动态申请权限,代码里别忘了处理权限申请的回调。
2. 核心实现代码
我们的思路是:记录上一次的有效位置,每次获取到新位置时,计算和上一次的距离并累加,最后把总距离显示在TextView里:
public class MainActivity extends AppCompatActivity implements LocationListener { private LocationManager locationManager; private TextView distanceTextView; private double totalTravelDistance = 0.0; private Location lastValidLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); distanceTextView = findViewById(R.id.tv_total_distance); // 获取LocationManager实例 locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // 动态申请定位权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1001); return; } // 开始监听位置更新:这里用GPS_PROVIDER,也可以根据需求换NETWORK_PROVIDER // 参数说明:定位提供者、最小更新时间(毫秒)、最小更新距离(米)、监听器 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); } @Override public void onLocationChanged(Location currentLocation) { // 过滤精度太差的位置数据,避免计算偏差 if (currentLocation.getAccuracy() > 10) { return; } if (lastValidLocation != null) { // 方式1:用distanceTo计算距离 float segmentDistance = lastValidLocation.distanceTo(currentLocation); totalTravelDistance += segmentDistance; // 方式2:用distanceBetween计算(和上面结果完全一致) // float[] distanceResult = new float[1]; // Location.distanceBetween(lastValidLocation.getLatitude(), lastValidLocation.getLongitude(), // currentLocation.getLatitude(), currentLocation.getLongitude(), distanceResult); // totalTravelDistance += distanceResult[0]; // 格式化显示结果,可按需转成公里 String displayText = String.format("总行驶距离:%.2f 米", totalTravelDistance); distanceTextView.setText(displayText); } // 更新上一次的有效位置 lastValidLocation = currentLocation; } // 以下是LocationListener的默认实现方法 @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override protected void onDestroy() { super.onDestroy(); // 停止监听,避免内存泄漏 if (locationManager != null) { locationManager.removeUpdates(this); } } }
3. 关键注意点
- 精度过滤:一定要判断
currentLocation.getAccuracy(),过滤掉精度超过10米的位置,不然计算出来的距离会有很大偏差。 - 官方推荐方案:如果是新项目,更建议用Google Play服务的
FusedLocationProviderClient获取位置,比原生LocationManager更稳定、功耗更低。 - 后台运行处理:如果需要后台持续计算,除了申请后台定位权限,还要做好后台保活逻辑,避免被系统回收。
关于你参考资料的困惑
《How to use android distanceBetween() method》里的用法其实很直白——你只需要传入两组经纬度,然后从你传入的float数组里取第一个元素就是距离值。它和distanceTo只是调用方式不同,计算结果完全一样,选哪个全看你手里的数据源形式。
内容的提问来源于stack exchange,提问作者Daniel Prado
相关产品推荐
相关产品推荐

