5

I am using LocationServices in my application. Before using location services I am trying to verify if Location with required settings is ON but the problem I am facing is that SettingsClient.checkSettings always failing. Please see my LocationRequest and LocationSettingRequest builder:

LocationRequest

 mLocationRequest = LocationRequest()
        mLocationRequest.interval = interval
        mLocationRequest.fastestInterval = interval

        Log.v(TAG, "distance => $distance")
        if(distance > 0) {
            mLocationRequest.smallestDisplacement = distance
        }

        mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        buildLocationSettingsRequest()

LocationSettingRequestBuilder

private fun buildLocationSettingsRequest() {
        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(mLocationRequest)
        mLocationSettingsRequest = builder.build()

        mSettingsClientInit = true
    }

And I am requesting checkSettings as

mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(this, object : OnSuccessListener<LocationSettingsResponse> {

                    override fun onSuccess(locationSettingsResponse: LocationSettingsResponse) {
                        Log.i(TAG, "LocationManager: All location settings are satisfied.");
                        mLocationCallback?.let {
                            fusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                        }
//                        updateUI();
                    }
                })
                .addOnFailureListener(this, object : OnFailureListener {
                    override fun onFailure(e: Exception) {
                        Log.v(TAG, "Request PErmission failure");
                        var statusCode = (e as ApiException).getStatusCode()
                        when (statusCode) {
                            LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                                try {
                                    // Show the dialog by calling startResolutionForResult(), and check the
                                    // result in onActivityResult().
                                    var rae = e as ResolvableApiException;
                                    rae.startResolutionForResult(this@BaseLocationActivity, REQUEST_CHECK_SETTINGS);
                                } catch (sie: IntentSender.SendIntentException) {
                                    Log.v(TAG, "PendingIntent unable to execute request.");
                                }
                            }
                            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                                mRequestingLocationUpdates = false;
                                Log.v(TAG, "Settings change unavailable.");
                            }

                        }
                    }
                }
                )

It is always resulting onFailure of addOnFailureListener. Can anyone please help me what can be the issue? This settings dialog shows OK to enable settings, I press OK, again same dialog appears with onFailure callback.

It is occuring on some devices, not on all devices.

Michiel Leegwater
  • 1,172
  • 4
  • 11
  • 27
Mustansar Saeed
  • 2,730
  • 2
  • 22
  • 46
  • Did you try with a different priority than `PRIORITY_HIGH_ACCURACY` ([see](https://stackoverflow.com/a/58331118/2668136))? – Blo Nov 27 '19 at 14:41
  • No, Even the device is in High accuracy mode that is Enable providers are Network and GPS , still this checkLocationSettings returns failure – Jinson Paul Nov 28 '19 at 04:39
  • @Mustansar Saeed refer dis ``` https://stackoverflow.com/a/10311891/12273964 ``` – Sandhiya Nov 28 '19 at 12:58

2 Answers2

2

Hello follow this code to resolve your problem, I added GPSUtils class with the help of this class you can easily manage GPS.

GpsUtils.Class

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import static android.content.ContentValues.TAG;
public class GpsUtils {
private Context context;
    private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationManager locationManager;
    private LocationRequest locationRequest;
public GpsUtils(Context context) {
        this.context = context;
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        mSettingsClient = LocationServices.getSettingsClient(context);
locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10 * 1000);
        locationRequest.setFastestInterval(2 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        mLocationSettingsRequest = builder.build();
//**************************
        builder.setAlwaysShow(true); //this is the key ingredient
        //**************************
    }
// method for turn on GPS
    public void turnGPSOn(onGpsListener onGpsListener) {
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            if (onGpsListener != null) {
                onGpsListener.gpsStatus(true);
            }
        } else {
            mSettingsClient
                    .checkLocationSettings(mLocationSettingsRequest)
                    .addOnSuccessListener((Activity) context, new OnSuccessListener<LocationSettingsResponse>() {
                        @SuppressLint("MissingPermission")
                        @Override
                        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//  GPS is already enable, callback GPS status through listener
                            if (onGpsListener != null) {
                                onGpsListener.gpsStatus(true);
                            }
                        }
                    })
                    .addOnFailureListener((Activity) context, new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            int statusCode = ((ApiException) e).getStatusCode();
                            switch (statusCode) {
                                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
                                        // Show the dialog by calling startResolutionForResult(), and check the
                                        // result in onActivityResult().
                                        ResolvableApiException rae = (ResolvableApiException) e;
                                        rae.startResolutionForResult((Activity) context, AppConstants.GPS_REQUEST);
                                    } catch (IntentSender.SendIntentException sie) {
                                        Log.i(TAG, "PendingIntent unable to execute request.");
                                    }
                                    break;
                                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                    String errorMessage = "Location settings are inadequate, and cannot be " +
                                            "fixed here. Fix in Settings.";
                                    Log.e(TAG, errorMessage);
Toast.makeText((Activity) context, errorMessage, Toast.LENGTH_LONG).show();
                            }
                        }
                    });
        }
    }
public interface onGpsListener {
        void gpsStatus(boolean isGPSEnable);
    }
}

GPS Dialog will be shown for SettingsClient’s failure callback and it will result in an activity’s onActivityResult(). So basically if the user agrees for turn on GPS, we can enable GPS flag in our activity.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == AppConstants.GPS_REQUEST) {
            isGPS = true; // flag maintain before get location
        }
    }
}

and now call GpsUtils class before getting a location.

new GpsUtils(this).turnGPSOn(new GpsUtils.onGpsListener() {
    @Override
    public void gpsStatus(boolean isGPSEnable) {
        // turn on GPS
        isGPS = isGPSEnable;
    }
});
Rahul Goswami
  • 762
  • 6
  • 18
  • 1
    The problem is even If all conditions for success listener is satisfied still in some devices onError is Occurring and it is not always,, – Jinson Paul Dec 03 '19 at 06:04
0

After doing a good amount of research I got a solution for this ...

The problem is basically if the LocationSettingsStatusCodes.RESOLUTION_REQUIRED == true then the next consecutive call you make will always result in the same output

i.e if you are calling this function recursively you will get RESOLUTION_REQUIRED always recursively so avoid calling this function recursively

How You Might be calling it recursively?

You might be getting the result_code of the resolution result and if its RESULT_OK you might be calling the same function to set up the location

for more info check my answer here for another similar question Android LocationServices.checkLocationSettings false negative result

AgentP
  • 6,261
  • 2
  • 31
  • 52