androidlocationnexus-7fusedlocationproviderapiandroid-fusedlocation

Android: Google Fused Location doesn't work while location is turned off


getLastLocation() returns NULL while phone location is Off on my 6.0 Nexus 7 tablet, but it works without GPS on another device. Why is it so and any way to solve it? I want to keep GPS off and just use network to get location.

Below is the class I am using to get location:

public class GPSCenter {
public static GoogleApiClient mGoogleApiClient;
public static Location mLastLocation;
private static Context mContext;

static GoogleApiClient.ConnectionCallbacks ccb = new GoogleApiClient.ConnectionCallbacks() {

    @Override
    public void onConnectionSuspended(int arg0) {
    }

    @Override
    public void onConnected(Bundle arg0) {

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        LocationRequest mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_NO_POWER);

        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    }
};
static GoogleApiClient.OnConnectionFailedListener odfl = new GoogleApiClient.OnConnectionFailedListener() {
    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
    }
};

public static synchronized void buildGoogleApiClient(Context c) {
    try {

        mContext = c;
        mGoogleApiClient = new GoogleApiClient.Builder(c)
                .addConnectionCallbacks(ccb)
                .addOnConnectionFailedListener(odfl)
                .addApi(LocationServices.API)
                .build();

        mGoogleApiClient.connect();
    } catch (Exception ex) {
        Log.i("location", "error " + ex.toString());
        ex.printStackTrace();
    }
}

public static double getLatitude(Context c) {
    try {
        return mLastLocation.getLatitude();
    } catch (Exception ex) {
        return 0.0;
    }
}

public static double getLongitude(Context c) {
    try {
        return mLastLocation.getLongitude();
    } catch (Exception ex) {
        return 0.0;
    }
}
}

Solution

  • It isn't because of the GPS thing but, the Location Settings is not enabled yet in the device, it is under your device Settings>Google>Services>Location, or Settings>Privacy&security>Location, or just Settings>Location. I got confused because in some device the drop-down status bar shows GPS enabling button and some shows Location enabling button. There is a way to enable the Location Settings automatically (without navigating user to device settings), it solved my issue, hope it helps you:

    After GoogleApiClient is connected, do a Location Settings checking as below:

    public static GoogleApiClient mGoogleApiClient;
    private static PendingResult<LocationSettingsResult> result;
    private static LocationSettingsRequest.Builder builder;
    public static Location mLastLocation;
    public static boolean isLocationON = false;
    
    public static synchronized void buildGoogleApiClient(Activity a, Context c) {
    
        try {
    
            mActivity = a;
            mContext = c;
            mGoogleApiClient = new GoogleApiClient.Builder(c)
                    .addConnectionCallbacks(ccb)
                    .addOnConnectionFailedListener(odfl)
                    .addApi(LocationServices.API)
                    .build();
    
            builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);
            builder.setAlwaysShow(true);
    
            mGoogleApiClient.connect();
    
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    private static GoogleApiClient.ConnectionCallbacks ccb = new GoogleApiClient.ConnectionCallbacks() {
    
        @Override
        public void onConnected(Bundle arg0) {
            checkLocationSettings();
        }
    
        @Override
        public void onConnectionSuspended(int arg0) {
        }
    };
    
    private static void checkLocationSettings() {
    
        result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
    
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
    
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
                final Status status = locationSettingsResult.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
    
                        isLocationON = true;
    
                        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                            return;
                        }
                        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    
                        if (mLocationSettingsListener != null) {
                            mLocationSettingsListener.onLocationON();
                        }
    
                        break;
    
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
    
                        isLocationON = false;
    
                        try {
                            // This line will check the result and prompt a dialog if the device location settings is not enabled
                            status.startResolutionForResult(mActivity, REQUEST_CHECK_SETTINGS);
    
                        } catch (IntentSender.SendIntentException e) {
                        }
                        break;
    
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        isLocationON = false;
                        // Location settings are unavailable so not possible to show any dialog now
                        if (mLocationSettingsListener != null) {
                            mLocationSettingsListener.onLocationError();
                        }
                        break;
                }
            }
        });
    }