我正在使用SettingsApi
并FusedLocationProvider
升级 Gps 设置并获取位置更新,我想要高精度位置更新,我正在显示打开 gps 对话框,SettingsApi
用于将 GPS 设置升级到高精度,但在某些设备(如 Mi 和 Gionee)中,即使用户在打开 Gps 对话框中单击了确定按钮我正在RESULT_CANCELED
继续,onActivityResult
而在摩托罗拉、联想等其他设备上一切正常
当用户在打开 Gps 对话框中单击时
- 如果 Gps 关闭,则将其打开并设置为仅设备模式(仅 Gps 模式)
onActivityResult
如果 Gps 处于打开状态,则 Gps 处于关闭状态,并且在这两种情况下我都会打开 RESULT_CANCELED
这是我的代码
- 位置助手
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();
}
- 活动代码
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
}
}