在某些设备中,无法使用FusedLocationProvider将Gps设置升级到高精度。

时间:2019-04-06 10:35:28

标签: android fusedlocationproviderapi android-fusedlocation fusedlocationproviderclient

我正在使用SettingsApiFusedLocationProvider来升级Gps设置并获取位置更新,我想要显示“使用SettingsApi打开GPS对话框来升级GPS的高精度位置更新”设置为“高精度”,但是在某些设备(例如Mi和Gionee)中,即使用户单击了“打开Gps对话框”中的“确定”按钮,我在RESULT_CANCELED上也得到了onActivityResult,而在其他设备上一切正常像摩托罗拉,联想

当用户在“打开Gps”对话框中单击

  1. 如果Gps处于关闭状态,则将其打开并设置为“仅设备模式”(“仅限Gps模式”)
  2. 如果Gps处于打开状态,则Gps处于关闭状态,两种情况下我都在onActivityResult上得到RESULT_CANCELED

这是我的密码

  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. 活动代码
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 个答案:

答案 0 :(得分:0)

库本身没有问题,问题在于名为FusedLocationProvider的应用程序转到设置->内置应用程序-> FusedLocationProvider->清除缓存和数据,现在您的应用程序可以正常运行了。

WorkAround#1:您可以选择

  1. LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY-更快的位置更新,但位置准确性可能较低
  2. LocationRequest.PRIORITY_LOW_POWER-速度较慢,或者可能没有位置更新(如果是室内或地下)

WorkAround#2:将用户重定向到“设置”页面

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