1

我正在使用SettingsApiFusedLocationProvider升级 Gps 设置并获取位置更新,我想要高精度位置更新,我正在显示打开 gps 对话框,SettingsApi用于将 GPS 设置升级到高精度,但在某些设备(如 Mi 和 Gionee)中,即使用户在打开 Gps 对话框中单击了确定按钮我正在RESULT_CANCELED继续,onActivityResult而在摩托罗拉、联想等其他设备上一切正常

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

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

这是我的代码

  1. 位置助手
    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
    }
}
4

1 回答 1

0

库本身没有问题,问题出在名为FusedLocationProvider“设置”->“安装应用程序”->“FusedLocationProvider”->“清除缓存和数据”的应用程序上,现在您的应用程序可以正常工作了。

解决方法#1:您可以选择

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

解决方法 #2:将用户重定向到设置页面

 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
 startActivityForResult(intent, REQUEST_UPDATE_GPS_SETTINGS_MANUALLY);
于 2019-04-24T06:38:21.113 回答