Not Able To Upgrade Gps settings to high Accuracy using FusedLocationProvider In some devices

时光怂恿深爱的人放手 提交于 2019-12-24 10:50:17

问题


I am using SettingsApi and FusedLocationProvider to upgrade Gps settings and getting location updates, I want High accuracy location updates for that I am showing Turn on gps dialog using SettingsApi to upgrade GPS settings to High Accuracy but in some devices (like Mi and Gionee) even if the user has clicked OK button in Turn On Gps Dialog I am getting RESULT_CANCELED on onActivityResult while everything is working perfectly fine in other devices like Motorola, Lenovo

When User is Clicking On in Turn On Gps dialog

  1. If Gps is Off then it is turned On and gets set to Device Only Mode (Gps Only Mode)
  2. If Gps is On then Gps is turned Off and I am getting RESULT_CANCELED on onActivityResult in both the cases

Here's My Code

  1. LocationHelper
    public class LocationHelper {

        private static final String TAG = LocationHelper.class.getSimpleName();

        private long updateIntervalInMilliseconds = 10000;

        private long fastestUpdateIntervalInMilliseconds = updateIntervalInMilliseconds / 2;

        private FusedLocationProviderClient mFusedLocationClient;

        private SettingsClient mSettingsClient;

        private LocationRequest mLocationRequest;

        private LocationSettingsRequest mLocationSettingsRequest;

        private LocationCallback mLocationCallback;


        private Boolean mRequestingLocationUpdates = false;


        private int requiredGpsPriority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;


        public LocationHelper(Context mContext) {
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
            mSettingsClient = LocationServices.getSettingsClient(mContext);
        }

        /**
         * Sets required gps priority
         * <p>
         * Gps Priority can be
         * <ul>
         * <li>LocationRequest.PRIORITY_HIGH_ACCURACY</li>
         * <li>LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY</li>
         * <li>LocationRequest.PRIORITY_NO_POWER</li>
         * <li>LocationRequest.PRIORITY_LOW_POWER</li>
         * </ul>
         * <p>
         * default is LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
         *
         * @param requiredGpsPriority gps priority
         */
        public void setRequiredGpsPriority(int requiredGpsPriority) {
            this.requiredGpsPriority = requiredGpsPriority;
        }

        /**
         * Sets Update Interval also sets fastestUpdateIntervalInMilliseconds to half of updateIntervalInMilliseconds
         * default is 10 seconds
         *
         * @param updateIntervalInMilliseconds update Interval
         */
        public void setUpdateInterval(long updateIntervalInMilliseconds) {
            this.updateIntervalInMilliseconds = updateIntervalInMilliseconds;
            this.fastestUpdateIntervalInMilliseconds = updateIntervalInMilliseconds / 2;
        }

        /**
         * Sets fastest Update Interval
         * default is 5 seconds
         *
         * @param fastestUpdateIntervalInMilliseconds fastest update Interval
         */
        public void setFastestUpdateIntervalInMilliseconds(long fastestUpdateIntervalInMilliseconds) {
            this.fastestUpdateIntervalInMilliseconds = fastestUpdateIntervalInMilliseconds;
        }


        public void init() {
            createLocationRequest();
            buildLocationSettingsRequest();
        }


        public void setLocationCallback(LocationCallback locationCallback) {
            this.mLocationCallback = locationCallback;
        }

        private void createLocationRequest() {
            mLocationRequest = new LocationRequest();

            mLocationRequest.setInterval(updateIntervalInMilliseconds);

            mLocationRequest.setFastestInterval(fastestUpdateIntervalInMilliseconds);

            mLocationRequest.setPriority(requiredGpsPriority);
        }


        private void buildLocationSettingsRequest() {
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(mLocationRequest);
            builder.setAlwaysShow(true);
            mLocationSettingsRequest = builder.build();
        }


        public boolean isRequestingForLocation() {
            return mRequestingLocationUpdates;
        }


        public void checkForGpsSettings(GpsSettingsCheckCallback callback) {

            if (mLocationSettingsRequest == null) {
                throw new IllegalStateException("must call init() before check for gps settings");
            }

            // Begin by checking if the device has the necessary jobLocation settings.
            mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
                    .addOnSuccessListener(locationSettingsResponse -> callback.requiredGpsSettingAreAvailable())
                    .addOnFailureListener(e -> {

                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                Log.i(TAG, "SuggestedLocation settings are not satisfied. notifying back to the requesting object ");

                                ResolvableApiException rae = (ResolvableApiException) e;
                                callback.requiredGpsSettingAreUnAvailable(rae);

                                break;

                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                Log.i(TAG, "Turn On SuggestedLocation From Settings. ");

                                callback.gpsSettingsNotAvailable();
                                break;
                        }

                    });
        }


        /**
         * Starts location updates from the FusedLocationApi.
         * <p>
         *     Consider Calling {@link #stopLocationUpdates()} when you don't want location updates it helps in saving battery
         * </p>
         */
        public void startLocationUpdates() {

            if (mLocationRequest == null) {
                throw new IllegalStateException("must call init() before requesting location updates");
            }

            if (mLocationCallback == null) {
                throw new IllegalStateException("no callback provided for delivering location updates,use setLocationCallback() for setting callback");
            }

            if (mRequestingLocationUpdates) {
                Log.d(TAG, "startLocationUpdates: already requesting location updates, no-op.");
                return;
            }

            Log.d(TAG, "startLocationUpdates: starting updates.");
            mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
                    .addOnCompleteListener(task -> mRequestingLocationUpdates = true);

        }

        public void stopLocationUpdates() {
            if (!mRequestingLocationUpdates) {
                Log.d(TAG, "stopLocationUpdates: updates never requested, no-op.");
                return;
            }

            Log.d(TAG, "stopLocationUpdates: stopping location updates.");
            mFusedLocationClient.removeLocationUpdates(mLocationCallback)
                    .addOnCompleteListener(task -> mRequestingLocationUpdates = false);
        }
}
  1. GpsSettingsCheckCallback
    public interface GpsSettingsCheckCallback {


        /**
         * We don't have required Gps Settings
         * ex For High Accuracy Locations We Need Gps In High Accuracy Settings
         *
         * How To show "Turn On Gps Dialog" ?
         * 
         * From Activity :
         * <code>status.startResolutionForResult(this , REQUEST_CHECK_SETTINGS);</code>
         * 
         * From Fragment :
         * <code>
         * startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null)
         * </code>
         */
        void requiredGpsSettingAreUnAvailable(ResolvableApiException status);


        /**
         * Everything's Good
         */
        void requiredGpsSettingAreAvailable();


        /**
         * Gps Settings Are Unavailable redirect user to settings page to turn on location
         */
        void gpsSettingsNotAvailable();
     }
  1. Activity Code
public class CheckGpsActivity extends AppCompatActivity {

    public static final String TAG = CheckGpsActivity.class.getSimpleName();
    public static final int REQUEST_LOCATION_SETTINGS_UPGRADE = 23;

    private Button turnOnLocationUpdatesBtn, turnOffLocationBtn, checkForRequredGpsSettingBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LocationHelper locationHelper = new LocationHelper(this);
        locationHelper.setRequiredGpsPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationHelper.init();

        locationHelper.setLocationCallback(new LocationCallback() {

            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                Location location = locationResult.getLocations().get(0);

                if (location != null)
                    Log.d(TAG, "Gps Coords" + location.getLatitude() + "," + location.getLongitude());
            }

        });

        turnOnLocationUpdatesBtn.setOnClickListener(view -> locationHelper.startLocationUpdates());

        turnOffLocationBtn.setOnClickListener(view -> locationHelper.startLocationUpdates());

        checkForRequredGpsSettingBtn.setOnClickListener(view -> {

            locationHelper.checkForGpsSettings(new GpsSettingsCheckCallback() {
                @Override
                public void requiredGpsSettingAreUnAvailable(ResolvableApiException status) {

                    Log.d(TAG, "require gps settings upgrade");
                    try {
                        status.startResolutionForResult(CheckGpsActivity.this, REQUEST_LOCATION_SETTINGS_UPGRADE);
                    } catch (IntentSender.SendIntentException e) {
                        e.printStackTrace();
                    }

                }

                @Override
                public void requiredGpsSettingAreAvailable() {
                    Log.d(TAG, "Gps Setting are just fine");
                }

                @Override
                public void gpsSettingsNotAvailable() {
                    Log.d(TAG, "Gps Setting unavailable, redirect to settings");
                }
            });

        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        //Result code I always get is 0 (RESULT_CANCELED) even if user clicked Ok in Turn On Location dialog
    }
}

回答1:


There is no issue with library itself, the problem is with an App called FusedLocationProvider go to Settings -> Intstalled Apps -> FusedLocationProvider -> Clear Cache & Data now your app will work Just fine.

WorkAround #1: You can opt for

  1. LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY - Faster Location Updates but location accuracy may be low
  2. LocationRequest.PRIORITY_LOW_POWER - Slower or maybe No Location Updates (if indoor or underground)

WorkAround #2: Redirect User to Settings Page

 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
 startActivityForResult(intent, REQUEST_UPDATE_GPS_SETTINGS_MANUALLY);


来源:https://stackoverflow.com/questions/55548220/not-able-to-upgrade-gps-settings-to-high-accuracy-using-fusedlocationprovider-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!