首页 > 解决方案 > 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服务,也无法提供位置

标签: androidandroid-locationandroid-fusedlocationfusedlocationproviderclient

解决方案


进一步调查显示,第一个问题是该设备具有过时的 google play 服务版本。谷歌播放服务没有更新的原因是由于 sim 限制。

对于所有想知道的人。

如何查看 google play 服务的版本:

1) 在设备上,您可以转到设置/应用程序,然后导航到 Google Play
服务,您可以在那里查看播放服务的版本。

2)您可以通过编程方式检查 google play 服务版本,有很多方法可以做到这一点。

您设备上的 google play 服务版本与当前公开可用版本的比较可以告诉您最新版本的 google play 服务是什么https://www.apkmirror.com/uploads/?q=google-play-services .


推荐阅读