2016-05-31 58 views
3

當我進入一個屏幕時,我檢查GPS是否打開,如果沒有,則顯示啓用GPS的對話框。當用戶點擊是時,onActivityResult - > GPS已打開,我嘗試獲取該位置,但始終返回空值。在對話框中啓用GPS後,Android位置返回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<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); 
     result.setResultCallback(new ResultCallback<LocationSettingsResult>() { 
      @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選擇是的,我的位置= 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; 
     } 
    } 

Editted:我做的片段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(); 
     } 
+0

檢查這個http://stackoverflow.com/questions/39490661/current-location-failed-googlemap/39491524#39491524鏈接 –

回答

0

LocationSettingsRequest使用只是讓位置設置足夠的,比如你要獲得更準確的(HIGH_ACCURACY)的位置,然後你需要啓用GPS。所以在這種情況下,LocationSettingsRequest會提示對話框允許更改api設置。

按確定後,您可以看到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。這是變空的第一個可能的原因。

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,這不是意外的行爲。這是獲取空值的第二個可能原因

您正在提出位置請求,但全局位置變量永遠不會在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. 
} 

這是得到空的第三個可能原因。

+0

我正在做我的片段中的權限請求,如果沒有被授予,提示用戶的權限..我們可以假設位置權限被授予,因爲我能夠在應用程序中的任何其他時間獲取位置,除了之後立即啓用GPS設置,也因爲我可以進入我的應用程序的信息,並看到該位置的權限被授予 – yellowmonkey

+0

基於我的研究,它似乎是因爲它正在尋找其他應用程序的最後一個已知位置,因爲沒有其他應用程序使用它,因爲它啓用它,這就是爲什麼它返回null。我只是不知道如何去解決這個問題 – yellowmonkey

+0

嗨,@ shiv.s。你有沒有找到任何解決方案?我也遇到了同樣的問題。 –

0

最後,我找到了一個解決方案: 我創建了一個線程並等待我的位置可用。

@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 
    } 
} 

這不是一個好的解決方案,但希望它會有所幫助。

0

添加對於我這種重寫方法及其工作fine--

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