问题
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
- If Gps is Off then it is turned On and gets set to Device Only Mode (Gps Only Mode)
- 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
- 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);
}
}
- 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();
}
- 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
LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
- Faster Location Updates but location accuracy may be lowLocationRequest.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