android - FusedLocationProviderClient 无法通过 3G 或 4G 网络获取 GPS 位置,除非先连接到 WIFI 网络
问题描述
我们的一个应用程序在商米的 T1 和 T2 mini 上运行。应用程序使用以下 LocationUtil 类发回设备的位置数据:
public class LocationUtil
{
private static final String TAG = LocationUtil.class.getSimpleName();
private final long UPDATE_INTERVAL_IN_MILLISECONDS = 20000;
private final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
private final int REQUEST_CHECK_SETTINGS = 100;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private LocationReceived locReceiveListener;
private boolean gettingUpdatesStarted;
private Context context;
public LocationUtil(){
}
public LocationUtil(Context context)
{
this.context = context;
}
public interface LocationReceived {
void onReceive(Location location);
void onError(String message);
}
private Activity actContext = null;
public void initialise(Activity context) {
this.actContext = context;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mSettingsClient = LocationServices.getSettingsClient(context);
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
if (mLocationCallback == null)
{
mLocationCallback = new LocationCallback()
{
@Override
public void onLocationResult(LocationResult locationResult)
{
super.onLocationResult(locationResult);
// location is received
mCurrentLocation = locationResult.getLastLocation();
locReceiveListener.onReceive(mCurrentLocation);
}
@Override
public void onLocationAvailability(LocationAvailability locationAvailability)
{
super.onLocationAvailability(locationAvailability);
}
};
}
}
public void StartLocationUpdater(LocationReceived locReceiveListenerIn){
locReceiveListener = locReceiveListenerIn;
if (!gettingUpdatesStarted)
{
gettingUpdatesStarted = true;
mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>()
{
@SuppressLint("MissingPermission")
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse)
{
Log.i(TAG, "All location settings are satisfied.");
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
}
})
.addOnFailureListener(new OnFailureListener()
{
@Override
public void onFailure(@NonNull Exception e)
{
int statusCode = ((ApiException) e).getStatusCode();
gettingUpdatesStarted = false;
switch (statusCode)
{
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
"location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the
// result in onActivityResult().
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult((Activity) actContext, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
String errorMessage = "Location settings are inadequate, and cannot be " +
"fixed here. Fix in Settings.";
Log.e(TAG, errorMessage);
}
}
});
}
}
public void getLastLocation(LocationReceived locReceiveListenerIn) {
locReceiveListener = locReceiveListenerIn;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
mFusedLocationClient.getLastLocation()
.addOnSuccessListener( new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
mCurrentLocation = location;
locReceiveListener.onReceive(mCurrentLocation);
}
else{
locReceiveListener.onError("No location received");
}
}
});
}
public void stopLocationUpdates() {
// Removing location updates
mFusedLocationClient
.removeLocationUpdates(mLocationCallback)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
gettingUpdatesStarted = false;
}
});
}
}
但是,似乎该应用程序仅在设备先连接到 WIFI 然后再切换回 3G 和 4G 时才能获取位置数据。首次连接到 3G 或 4G 网络时,设备不会发送任何位置数据。经测试,发现如下:
结果是 3G 的初始定位可以成功,但速度很慢。代码使用了GMS的融合定位方案。当设备通过记录请求位置信息时,设备很快就会得到基站的位置信息。GMS使用基站的位置信息来分析设备的经纬度。但是三分钟后,GMS 进程打印出没有位置的日志,而您的应用程序仍然没有位置信息。但过了一段时间,该应用程序能够从 4G 网络中获取信息。根据目前掌握的信息,怀疑是GMS向应用返回位置有问题
即使使用最新的google play服务,也无法提供位置
解决方案
进一步调查显示,第一个问题是该设备具有过时的 google play 服务版本。谷歌播放服务没有更新的原因是由于 sim 限制。
对于所有想知道的人。
如何查看 google play 服务的版本:
1) 在设备上,您可以转到设置/应用程序,然后导航到 Google Play
服务,您可以在那里查看播放服务的版本。
2)您可以通过编程方式检查 google play 服务版本,有很多方法可以做到这一点。
您设备上的 google play 服务版本与当前公开可用版本的比较可以告诉您最新版本的 google play 服务是什么https://www.apkmirror.com/uploads/?q=google-play-services .
推荐阅读
- python - 似乎无法使用 twitter JSON 数据集
- python - 如果有人提到机器人,如何让机器人做出回应?
- angularjs - 我可以在 textangular 中获得编辑器文本的应用样式对象吗
- php - wordpress 自定义 add_rewrite_rule 不适用于分页
- java - 未能执行目标 org.apache.maven.plugins:maven-surefire-plugin:2.4.3:test
- python - 通过对列进行分组来连接连续的行
- azure - Azure Functions - v2 支持和 v1 生命周期
- php - 正则表达式获取字符串的几个部分,然后用新字符串替换所有内容
- ios - 自动布局根据屏幕大小进行设计ios
- cassandra - Thingsboard 集群设置