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

Android Studio中FusedLocationProviderClient定位偶尔失效的解决方案咨询

How to Reliably Get User Location in Android Studio

Great question! The issue you're hitting with getLastLocation() is really common—let me break down why it happens and walk you through a rock-solid solution to get a location every time.

Why getLastLocation() Fails Sometimes

The getLastLocation() method only returns the last cached location the system has stored. If your device hasn't had a recent location fix (like on first app launch, after turning on location services, or if it's been hours since the last update), this method will return null—which triggers that error toast you're seeing. Also, quick typo in your code: you used SearchActivity.this in the error toast, but it should be LocationActivity.this to avoid a context mismatch.

Step-by-Step Reliable Implementation

Let's build a solution that actively requests a fresh location instead of relying on cached data, plus handles permissions and location service checks.

1. Add Permissions to AndroidManifest.xml

First, make sure you have the necessary permissions declared:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Add this only if you need background location access (Android 12+) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="33" />

2. Dynamic Permission Request

Since location permissions are "dangerous" permissions, you need to ask the user for approval at runtime:

private static final int REQUEST_LOCATION_PERMISSION = 100;

private boolean checkLocationPermissions() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        return true;
    }
    // Request permission if not granted
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            REQUEST_LOCATION_PERMISSION);
    return false;
}

// Handle permission request result
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_LOCATION_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission granted, start location request
            requestFreshLocation();
        } else {
            Toast.makeText(this, "Location permission is required to get your location", Toast.LENGTH_LONG).show();
        }
    }
}

3. Check if Location Services are Enabled

Before requesting location, verify that the user has turned on location services. If not, send them to settings to enable it:

private boolean isLocationEnabled() {
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
            || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}

private void promptEnableLocation() {
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivity(intent);
}

4. Request Fresh Location Updates

Instead of getLastLocation(), use requestLocationUpdates() to get a live location fix. We'll also use a LocationCallback to handle the result, and clean up updates when we're done to save battery:

private FusedLocationProviderClient fusedLocationProviderClient;
private LocationCallback locationCallback;
private LocationRequest locationRequest;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_location);

    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
    setupLocationCallback();
    setupLocationRequest();

    // Check permissions and location services first
    if (checkLocationPermissions()) {
        if (isLocationEnabled()) {
            requestFreshLocation();
        } else {
            promptEnableLocation();
            Toast.makeText(this, "Please enable location services", Toast.LENGTH_LONG).show();
        }
    }
}

private void setupLocationRequest() {
    locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // Use PRIORITY_BALANCED_POWER_ACCURACY for lower battery use
    locationRequest.setInterval(10000); // 10 seconds interval (adjust as needed)
    locationRequest.setFastestInterval(5000); // Fastest update interval
}

private void setupLocationCallback() {
    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(@NonNull LocationResult locationResult) {
            super.onLocationResult(locationResult);
            if (locationResult != null && locationResult.getLocations().size() > 0) {
                int latestLocationIndex = locationResult.getLocations().size() - 1;
                Location location = locationResult.getLocations().get(latestLocationIndex);
                
                // Use the location data
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                String latitudeStr = String.valueOf(latitude);
                String longitudeStr = String.valueOf(longitude);
                
                Toast.makeText(LocationActivity.this, latitudeStr + " " + longitudeStr, Toast.LENGTH_LONG).show();
                
                // Stop location updates once we have the location to save battery
                fusedLocationProviderClient.removeLocationUpdates(locationCallback);
            } else {
                Toast.makeText(LocationActivity.this, "Your Location Could Not Be Found !!!", Toast.LENGTH_LONG).show();
            }
        }
    };
}

private void requestFreshLocation() {
    try {
        fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
    } catch (SecurityException e) {
        // This shouldn't happen if we checked permissions first, but handle it just in case
        e.printStackTrace();
        Toast.makeText(this, "Location permission not granted", Toast.LENGTH_LONG).show();
    }
}

// Clean up location updates when activity is paused/destroyed to avoid memory leaks
@Override
protected void onPause() {
    super.onPause();
    if (fusedLocationProviderClient != null && locationCallback != null) {
        fusedLocationProviderClient.removeLocationUpdates(locationCallback);
    }
}

Key Notes

  • Priority Setting: Use PRIORITY_HIGH_ACCURACY for precise GPS location, or PRIORITY_BALANCED_POWER_ACCURACY if you don't need pinpoint accuracy and want to save battery.
  • Stop Updates: Always call removeLocationUpdates() once you have the location (or when the activity is paused) to prevent unnecessary battery drain.
  • Edge Cases: The code handles permission denials, disabled location services, and security exceptions to make your app robust.

This implementation will reliably get a fresh location every time, instead of relying on potentially stale cached data.

内容的提问来源于stack exchange,提问作者Rick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:50:00