FusedLocationProviderClient 无法通过 3G 或 4G 网络获取 GPS 位置,除非先连接到 WIFI 网络

Posted

技术标签:

【中文标题】FusedLocationProviderClient 无法通过 3G 或 4G 网络获取 GPS 位置,除非先连接到 WIFI 网络【英文标题】:FusedLocationProviderClient cannot get GPS location over 3G or 4G network unless first connected to WIFI network 【发布时间】:2020-01-30 16:43:49 【问题描述】:

我们的一个应用程序正在商米的 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服务,也无法提供位置

【问题讨论】:

【参考方案1】:

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

对于所有想知道的人。

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

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

2) 您可以通过编程方式查看 google play 服务版本,有 有无数种方法可以做到这一点。

对比你设备上的google play服务版本和当前公开的版本可以告诉你google play服务的最新版本是https://www.apkmirror.com/uploads/?q=google-play-services。

【讨论】:

您是如何得知这一消息的?解决方案是什么?

以上是关于FusedLocationProviderClient 无法通过 3G 或 4G 网络获取 GPS 位置,除非先连接到 WIFI 网络的主要内容,如果未能解决你的问题,请参考以下文章