如何实现当前坐标在目标坐标10米半径内的校验?现有代码仅判断1公里
10米半径坐标校验的代码问题及修正方案
我需要判断当前设备坐标是否在目标坐标的10米范围内,自己写了一段代码但不确定可靠性。现在发现代码里只做了1公里范围的判断,不知道怎么改成10米的校验,也不清楚代码有没有其他潜在问题。原代码如下:
punchin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { punchout.setVisibility(View.VISIBLE); punchin.setVisibility(View.INVISIBLE); curLocation.setText(""); tarLocation.setText(""); String androidID = getIMEINumber(); if (androidID != null) { getCurrentLocation(); // Execute the Api's double targetLatitude = 19.2185561;// Specify the latitude of the target location double targetLongitude = 72.86228096;// Specify the longitude of the target location float[] distanceResults = new float[1]; Location.distanceBetween(latitude, longitude, targetLatitude, targetLongitude, distanceResults); float distanceInKm = distanceResults[0] / 1000; String currentLocationStr = "Current :-" + latitude + " : " + longitude; String targetLocationStr = "Target :-" + targetLatitude + " : " + targetLongitude; if (distanceInKm < 1) { curLocation.setText(currentLocationStr); tarLocation.setText(targetLocationStr); Toast.makeText(requireContext(), "You are under office premises ", Toast.LENGTH_LONG).show(); } else { curLocation.setText(currentLocationStr); tarLocation.setText(targetLocationStr); Toast.makeText(requireContext(), "You are not under office premises ", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(getContext(), "No Data", Toast.LENGTH_SHORT).show(); } } }); private void getCurrentLocation() { FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext()); if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request location permissions if not already granted ActivityCompat.requestPermissions((Activity) requireContext(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101); } else { // Permissions already granted, request current location fusedLocationClient.getLastLocation() .addOnSuccessListener(location -> { if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); // Use the obtained latitude and longitude values for further processing // You can compare these values with your desired geolocation } }) .addOnFailureListener(e -> { // Handle any errors that occurred while getting the location }); } }
原代码存在的问题
- 异步时序错误:
getCurrentLocation是异步调用,调用后立刻计算距离时,latitude和longitude可能还没被赋值(getLastLocation的回调还没执行),导致用旧值或默认值计算,结果完全不准确。 - 距离判断逻辑错误:原代码把计算出的米数转成公里后判断是否小于1(即1公里),但需求是10米,应该直接用原始米数和10比较。
- 权限回调缺失:请求权限后,用户授权成功时没有重新触发位置获取和校验逻辑,导致授权后功能不生效。
修正后的完整代码
punchin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { punchout.setVisibility(View.VISIBLE); punchin.setVisibility(View.INVISIBLE); curLocation.setText(""); tarLocation.setText(""); String androidID = getIMEINumber(); if (androidID != null) { // 直接触发位置获取+校验逻辑 getCurrentLocationAndCheck(); } else { Toast.makeText(getContext(), "No Data", Toast.LENGTH_SHORT).show(); } } }); // 合并位置获取与校验逻辑,避免异步时序问题 private void getCurrentLocationAndCheck() { FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireContext()); if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions((Activity) requireContext(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101); return; } fusedLocationClient.getLastLocation() .addOnSuccessListener(location -> { if (location != null) { double currentLat = location.getLatitude(); double currentLng = location.getLongitude(); double targetLatitude = 19.2185561; double targetLongitude = 72.86228096; // 计算距离,结果单位为米 float[] distanceResults = new float[1]; Location.distanceBetween(currentLat, currentLng, targetLatitude, targetLongitude, distanceResults); float distanceInMeters = distanceResults[0]; String currentLocationStr = "Current :-" + currentLat + " : " + currentLng; String targetLocationStr = "Target :-" + targetLatitude + " : " + targetLongitude; curLocation.setText(currentLocationStr); tarLocation.setText(targetLocationStr); // 判断是否在10米范围内 if (distanceInMeters <= 10) { Toast.makeText(requireContext(), "你在办公区域内", Toast.LENGTH_LONG).show(); // 此处可执行打卡API请求 } else { Toast.makeText(requireContext(), "你不在办公区域内", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(requireContext(), "无法获取当前位置", Toast.LENGTH_SHORT).show(); } }) .addOnFailureListener(e -> { Toast.makeText(requireContext(), "获取位置失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); }); } // 处理权限请求结果 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 101) { boolean hasFineLocation = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; boolean hasCoarseLocation = grantResults.length > 1 && grantResults[1] == PackageManager.PERMISSION_GRANTED; if (hasFineLocation || hasCoarseLocation) { // 授权成功后重新执行位置校验 getCurrentLocationAndCheck(); } else { Toast.makeText(requireContext(), "需要位置权限才能进行打卡", Toast.LENGTH_SHORT).show(); } } }
关键修改说明
- 合并异步逻辑:把位置获取和距离校验放到同一个方法中,确保只有拿到最新位置后才计算距离,彻底解决时序问题。
- 修正距离判断:直接使用
distanceResults[0](单位为米)与10比较,完全符合10米半径的需求。 - 补充权限回调:实现
onRequestPermissionsResult方法,用户授权后自动重新触发校验逻辑。 - 完善错误提示:增加位置获取失败、无法获取位置的提示,提升用户体验。
内容的提问来源于stack exchange,提问作者sagar raval
相关产品推荐
相关产品推荐

