You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:36:44