使用distanceTo无法显示手机移动距离,请求排查问题
Let's Fix Your Distance Tracking Issue
Hey there! No need to apologize for your English—we're all here to troubleshoot together. Let's break down the problems in your code and address the permission concerns first:
1. Permission Handling Problem
Your current code only checks if permissions are granted, but it doesn't request permissions if they're missing. On Android 6.0 (API 23+) and above, you need to ask the user explicitly for location permissions. Skipping this step means your app can't access location data at all, which would definitely break your distance tracking.
2. Critical Logic Bugs in Your Code
There are a few issues that would prevent the distance from calculating correctly (or even crash your app):
- You're calling
onLocationChanged(null)directly inonCreate—this setsmCurrentLocationto null, leading to null pointer exceptions when you try to calldistanceTo(). - You don't check if
locationis null inonLocationChanged—GPS can take time to get a fix, so early callbacks might pass null. - Your distance calculation logic doesn't handle cases where location data isn't yet available.
Fixed Code Example
Location mCurrentLocation, lStart, lEnd; float dist = 0; private static final int LOCATION_PERMISSION_REQUEST_CODE = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Check and request permissions first 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, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE); return; } // Start location updates only if permissions are granted startLocationTracking(); } private void startLocationTracking() { LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } } @Override public void onLocationChanged(Location location) { // Skip if location data is invalid if (location == null) { return; } mCurrentLocation = location; if (lStart == null) { // Initialize with first valid location lStart = location; lEnd = location; } else { lEnd = location; } updateDistanceUI(); } private void updateDistanceUI() { TextView txt2 = findViewById(R.id.textView2); // Calculate distance only if both locations are valid if (lStart != null && lEnd != null) { dist += lStart.distanceTo(lEnd); txt2.setText(String.format("%.2f m", dist)); // Format for cleaner display lStart = lEnd; // Update start point for next calculation } else { txt2.setText("Waiting for location..."); } } // Handle permission request result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) { boolean hasFinePermission = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; boolean hasCoarsePermission = grantResults.length > 1 && grantResults[1] == PackageManager.PERMISSION_GRANTED; if (hasFinePermission || hasCoarsePermission) { startLocationTracking(); } else { Toast.makeText(this, "Location permissions are required to track distance", Toast.LENGTH_LONG).show(); } } }
Key Changes Explained
- Proper Permission Flow: Now we request permissions if they're missing, and start location updates only after the user grants them.
- Null Safety Checks: We avoid crashes by validating
locationbefore using it. - Removed Invalid
onLocationChanged(null)Call: This was causing initial null values that broke the calculation. - Better UI Feedback: We show a message while waiting for the first GPS fix.
- Formatted Distance Output: Using
String.formatmakes the distance value easier to read.
Test this code outdoors (GPS needs clear sky access) and make sure to grant location permissions when prompted—it should start tracking your distance correctly!
内容的提问来源于stack exchange,提问作者Raúl

