在对话框中启用GPS后,Android位置返回null

当我进入屏幕时,我检查GPS是否打开,如果没有,则显示启用GPS的对话框。 当用户单击是时,onActivityResult – > GPS已打开,我尝试获取该位置,但这始终返回null

当我进入已经打开GPS的屏幕时,可以正确检索位置。 我几天来一直苦苦挣扎,似乎找不到任何资源。

UserLocationUtilities.java

public class UserLocationUtilities implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener{ GoogleApiClient googleApiClient; Activity activity; protected static final int REQUEST_CHECK_SETTINGS = 0x1; boolean isGPSEnabled = false; // flag for network status boolean isNetworkEnabled = false; // flag for GPS status boolean canGetLocation = false; protected LocationManager locationManager; protected LocationListener locationListener; protected Location location; protected double latitude,longitude; protected boolean gps_enabled,network_enabled; // The minimum distance to change Updates in meters private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 1 * 1000 * 60; // 1 minute public UserLocationUtilities(Activity activity){ this.activity = activity; } public void settingsRequest() { if(googleApiClient == null){ googleApiClient = new GoogleApiClient.Builder(activity) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this).build(); googleApiClient.connect(); } LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(30 * 1000); locationRequest.setFastestInterval(5 * 1000); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() .addLocationRequest(locationRequest); builder.setAlwaysShow(true); //this is the key ingredient PendingResult result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); result.setResultCallback(new ResultCallback() { @Override public void onResult(LocationSettingsResult result) { final Status status = result.getStatus(); final LocationSettingsStates state = result.getLocationSettingsStates(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: // All location settings are satisfied. The client can initialize location // requests here. break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: // Location settings are not satisfied. But could be fixed by showing the user // a dialog. try { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). status.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { // Ignore the error. } break; case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: // Location settings are not satisfied. However, we have no way to fix the // settings so we won't show the dialog. break; } } }); } public Location getLocation() { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { try { locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE); isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // no network provider is enabled } else { this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } // if GPS Enabled get lat/long using GPS Services if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } } return location; } public boolean isLocationEnabled() { int locationMode = 0; String locationProviders; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ try { locationMode = Settings.Secure.getInt(activity.getApplicationContext().getContentResolver(), Settings.Secure.LOCATION_MODE); } catch (Settings.SettingNotFoundException e) { e.printStackTrace(); } return locationMode != Settings.Secure.LOCATION_MODE_OFF; }else{ locationProviders = Settings.Secure.getString(activity.getApplicationContext().getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); return !TextUtils.isEmpty(locationProviders); } } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } } 

用户在设置对话框,onActivityResult中选择是后,我执行location = userlocationutilities.getLocation(); 并始终返回null。 如果切换屏幕并返回,则检索位置。

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { // Check for the integer request code originally supplied to startResolutionForResult(). case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: //location settings dialog, user selected YES to enabling location location = userLocationUtilities.getLocation(); if(location != null){ //location of user FOUND Toast.makeText(getActivity(), "Lat: "+location.getLatitude()+" Long: "+location.getLongitude(), Toast.LENGTH_LONG).show(); getRingsNearMeCall(); }else{ //location of user NOT FOUND Toast.makeText(getActivity(), "null location", Toast.LENGTH_LONG).show(); } break; case Activity.RESULT_CANCELED: //location settings dialog, user selected NO to enabling location userLocationUtilities.settingsRequest(); //ask user again with Location Settings Dialog break; } break; } } 

编辑:我在片段中创建requestPermission,授予权限

 if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(getActivity(), new String[] { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSION_ACCESS_FINE_LOCATION); }else{ checkLocationSettingsGetRings(); } 

最后,我找到了一个解决方案:我创建一个线程并等待我的位置可用。

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode){ case REQUEST_LOCATION: switch (resultCode){ case Activity.RESULT_OK: mHandler = new Handler(); runnable = new Runnable() { @Override public void run() { mHandler.postDelayed(this,1000); checkLocationAvailable(); } }; mHandler.postDelayed(runnable,1000); break; case Activity.RESULT_CANCELED: break; } } } 

在我的位置可用时创建一个停止线程的函数。

 private void checkLocationAvailable(){ if (mMap.getMyLocation() != null) { mHandler.removeCallbacks(runnable); // do stuff } } 

这不是一个好的解决方案,但希望它会有所帮助。

为我添加这种覆盖方法它的工作正常 –

@Override public void onLocationChanged(Location location) { getLocation("onLocationChanged"); }

LocationSettingsRequest仅用于使位置设置充足,例如您希望获得更准确(HIGH_ACCURACY)的位置,然后您需要启用GPS。 因此,在这种情况下,LocationSettingsRequest会提示对话框以允许api更改设置。

按OK后,您可以看到GPS已启用。 但这并不意味着您已获准提出位置请求。

 @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CHECK_SETTINGS: switch (resultCode) { case Activity.RESULT_OK: // Here means required settings are adequate. // We can make location request. // But are we granted to use request location updates ? break; } break; } } } 

多数民众赞成,但你正在检查许可,但你从未做过requestPermissions 。 这是获得null的第一个可能原因。

 public Location getLocation() { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { ... } return location; } 

即使您以前被授予过位置请求

  location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 

getLastKnownLocation()方法可以返回null,这不是意外行为。 这是获得null的第二个可能原因

您正在进行位置请求,但从未在onLocationChanged回调中分配全局位置变量。

  @Override public void onLocationChanged(Location location) { // global location variable is not assigned ? // getLocation() method will return null if getLastKnownLocation() // did not return null previously. } 

这是获得null的第三个可能原因。