代码之家  ›  专栏  ›  技术社区  ›  m3g4tr0n

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

  •  0
  • m3g4tr0n  · 技术社区  · 7 年前

    我正在使用 SettingsApi FusedLocationProvider 要升级GPS设置并获取位置更新,我需要高精度的位置更新,因为我正在显示使用 设置SAPI 要将GPS设置升级到高精度,但在某些设备(如MI和Gionee)中,即使用户已依次单击“确定”按钮打开GPS对话框,我也会得到 RESULT_CANCELED onActivityResult 而在摩托罗拉、联想等其他设备上,一切运行正常

    当用户点击打开GPS对话框时

    1. 如果GPS关闭,则它将打开并设置为仅设备模式(仅GPS模式)
    2. 如果GPS打开,则GPS关闭,我将在上获得取消的结果 活动结果 在这两种情况下

    这是我的密码

    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
        }
    }
    
    0 回复  |  直到 7 年前
        1
  •  0
  •   m3g4tr0n    7 年前

    库本身没有问题,问题是一个名为 FusedLocationProvider 转到“设置”->“Intstalled Apps”->“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);
    
    推荐文章