Android Studio中如何计算Firebase里LatLng标记与当前位置的距离
如何计算并显示Firebase标记到当前位置的距离
嘿,我来帮你搞定这个问题!要把Firebase里的3个标记到你当前位置的距离显示出来,咱们分几步来操作就行:
步骤1:先搞定当前位置的获取(记得配置权限)
首先得确保你的App已经获取了位置权限,先在AndroidManifest.xml里加上这两行:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
然后用Google的FusedLocationProviderClient来获取最新的设备位置,代码示例如下:
private FusedLocationProviderClient fusedLocationClient; private LatLng currentLocation; // 用来存当前位置的坐标 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // 先检查权限,没有的话就请求 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100); return; } // 获取最后已知位置 fusedLocationClient.getLastLocation() .addOnSuccessListener(this, location -> { if (location != null) { currentLocation = new LatLng(location.getLatitude(), location.getLongitude()); // 位置拿到后,再加载Firebase的标记数据 loadFirebaseMarkers(); } }); }
步骤2:计算标记与当前位置的距离
在你现有的ChildEventListener里,拿到每个标记的坐标后,用Android自带的Location.distanceBetween()方法计算直线距离(单位是米),之后可以转换成公里或者你需要的单位,再把距离显示在标记的提示框里:
private void loadFirebaseMarkers() { DatabaseReference refDatabase = FirebaseDatabase.getInstance().getReference("你的标记数据节点"); refDatabase.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { // 从Firebase取出标记的坐标和名称 Double lat = dataSnapshot.child("latitude").getValue(Double.class); Double lng = dataSnapshot.child("longitude").getValue(Double.class); LatLng markerLocation = new LatLng(lat, lng); String nama = dataSnapshot.child("nama").getValue(String.class); // 假设你有名称字段 if (currentLocation != null) { // 计算两点之间的距离 float[] distanceResult = new float[1]; Location.distanceBetween( currentLocation.latitude, currentLocation.longitude, markerLocation.latitude, markerLocation.longitude, distanceResult ); float distanceInMeters = distanceResult[0]; // 转换成公里,保留一位小数 double distanceInKm = Math.round(distanceInMeters / 1000.0 * 10) / 10.0; // 创建标记,把距离放在snippet里,点击标记就会显示 mMap.addMarker(new MarkerOptions() .position(markerLocation) .title(nama) .snippet("距离当前位置:" + distanceInKm + " km")); } else { // 如果还没获取到当前位置,先显示标记,后续再更新 mMap.addMarker(new MarkerOptions() .position(markerLocation) .title(nama) .snippet("正在获取位置...")); } } // 其他回调方法按需实现 @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) {} }); }
步骤3:处理权限请求的结果
别忘了加上权限请求的回调,确保用户授权后能重新获取位置:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,重新获取位置 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> { if (location != null) { currentLocation = new LatLng(location.getLatitude(), location.getLongitude()); loadFirebaseMarkers(); } }); } } else { Toast.makeText(this, "需要位置权限才能显示距离哦", Toast.LENGTH_SHORT).show(); } } }
额外小提示
- 如果需要实时更新距离(比如用户移动时),可以用
requestLocationUpdates监听位置变化,然后遍历所有标记更新距离。 - 这里计算的是直线距离(鸟飞距离),如果需要导航路径的实际距离,得用Google Maps Directions API。
内容的提问来源于stack exchange,提问作者husen
相关产品推荐
相关产品推荐

