无法使用 FusedLocationProvider 将 Gps 设置升级到高精度在某些设备中
Posted
技术标签:
【中文标题】无法使用 FusedLocationProvider 将 Gps 设置升级到高精度在某些设备中【英文标题】:Not Able To Upgrade Gps settings to high Accuracy using FusedLocationProvider In some devices 【发布时间】:2019-08-28 02:45:30 【问题描述】:我正在使用 SettingsApi
和 FusedLocationProvider
升级 Gps 设置并获取位置更新,我想要高精度位置更新,我正在显示使用 SettingsApi
打开 gps 对话框以将 GPS 设置升级到高精度,但在某些设备(例如 Mi 和 Gionee)即使用户在打开 Gps 对话框中单击了 OK 按钮,我在 onActivityResult
上收到 RESULT_CANCELED
而在摩托罗拉、联想等其他设备上一切正常
当用户在打开 Gps 对话框中单击时
-
如果 Gps 处于关闭状态,则将其打开并设置为仅设备模式(仅 Gps 模式)
如果 Gps 开启,则 Gps 关闭,在这两种情况下,
onActivityResult
都会出现 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
【问题讨论】:
你有什么解决方案吗,因为我在小米手机中也遇到了同样的问题。在 onActivityResult() 它总是去 Activity.RESULT_CANCELED 查看我的答案 【参考方案1】:库本身没有问题,问题出在名为 FusedLocationProvider
的应用程序上,转到设置 -> 安装应用程序 -> FusedLocationProvider -> 清除缓存和数据,现在您的应用程序可以正常工作了。
解决方法#1:您可以选择
LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
- 位置更新速度更快,但位置准确性可能较低
LocationRequest.PRIORITY_LOW_POWER
- 位置更新较慢或可能没有位置更新(如果是室内或地下)
解决方法 #2:将用户重定向到设置页面
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, REQUEST_UPDATE_GPS_SETTINGS_MANUALLY);
【讨论】:
以上是关于无法使用 FusedLocationProvider 将 Gps 设置升级到高精度在某些设备中的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 StorageClass 配置卷 - 无法获取存储帐户的存储密钥