GPS已启用仍无法获取设备位置,应用卡在白对话框的技术解决方案咨询
Let’s work through your problems step by step—from the GPS retrieval failures and stuck dialog to the duplicate code redundancy:
1. Resolve GPS Location Not Being Retrieved (Even When Enabled)
Your current code only checks if GPS is enabled, but misses critical steps for reliable location retrieval and device compatibility. Here’s what to adjust:
Ensure Proper Dynamic Permission Handling
YourLocationPremissionCheck()might not be handling Android 6.0+ runtime permissions correctly. Explicitly requestACCESS_FINE_LOCATIONand handle the user’s response:private static final int LOCATION_PERM_REQUEST_CODE = 1001; private void LocationPremissionCheck() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERM_REQUEST_CODE); } else { // Proceed with location setup once permission is granted startLocationUpdates(); } } // Handle permission grant/denial result @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERM_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startLocationUpdates(); } else { Toast.makeText(this, "Location permission is required to use this feature", Toast.LENGTH_SHORT).show(); } } }Switch to Fused Location Provider (More Reliable Than Raw
LocationManager)
The nativeLocationManagerhas poor cross-device compatibility. Google’s Fused Location Provider is designed for consistent location results:private FusedLocationProviderClient fusedLocationClient; private LocationCallback locationCallback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.remind_activity); fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // ... other initialization code LocationPremissionCheck(); GooglePlayServiceCheck(); } private void startLocationUpdates() { LocationRequest locationRequest = LocationRequest.create(); locationRequest.setInterval(10000); // 10 seconds locationRequest.setFastestInterval(5000); // 5 seconds locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) return; for (Location location : locationResult.getLocations()) { // Use the retrieved location here Log.d("Location", "Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude()); } } }; if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()); }Enforce High-Accuracy Location Mode
Some devices have GPS enabled but use battery-saving (low-accuracy) mode. Add a check to prompt users to switch to high accuracy:private void checkLocationSettings() { LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); SettingsClient client = LocationServices.getSettingsClient(this); Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build()); task.addOnFailureListener(this, e -> { if (e instanceof ResolvableApiException) { // Show dialog to enable high-accuracy mode try { ResolvableApiException resolvable = (ResolvableApiException) e; resolvable.startResolutionForResult(this, 1002); } catch (IntentSender.SendIntentException sendEx) { // Ignore error } } }); }
2. Fix the Stuck White Dialog Issue
The dialog gets stuck because you’re showing it only in onCreate() and not handling the return from the location settings screen. Here’s the fix:
Move GPS Check to
onResume()
This ensures the check runs every time the activity comes to the foreground (e.g., after the user returns from enabling GPS):@Override protected void onResume() { super.onResume(); GPSLocationServiceCheck(); }Handle Return from Location Settings
AddonActivityResult()to re-verify GPS status after the user exits the settings screen:@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1002) { if (resultCode == RESULT_OK) { // GPS is now enabled—start location updates startLocationUpdates(); } else { Toast.makeText(this, "GPS is required to use this app", Toast.LENGTH_SHORT).show(); startActivity(new Intent(this, StartActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); finish(); } } }
3. Eliminate Duplicate GPSLocationServiceCheck() Code
Extract the duplicate method into a reusable utility class to avoid repeating code across files:
- Create
LocationUtils.java:
public class LocationUtils { public static void showGPSDisabledPrompt(Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setMessage("Your GPS seems to be disabled, enable it to use this app?") .setCancelable(false) .setPositiveButton("Yes", (dialog, id) -> { context.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); }) .setNegativeButton("No", (dialog, id) -> { dialog.cancel(); Intent intent = new Intent(context, StartActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(intent); ((Activity) context).finish(); }); AlertDialog alert = builder.create(); alert.show(); } } }
- Replace all calls to
GPSLocationServiceCheck()with:
LocationUtils.showGPSDisabledPrompt(this);
内容的提问来源于stack exchange,提问作者HDD

