2022年11月后Android Go设备GPS_PROVIDER与NETWORK_PROVIDER返回NULL如何解决?
也许某天这能帮到别人。
背景
2022年11月23日左右,我们团队收到用户反馈,一款通过定位验证员工是否在指定地点打卡考勤的App出现问题。
实现逻辑为将当前GPS坐标与预存的工作地点坐标比对。
部分使用Go Edition设备的用户完全无法获取GPS精度,而App要求GPS精度在目标地点200米范围内才能开始工作,导致这些用户无法正常使用!
原本通过LocationManager直接调用GPS硬件实现定位,代码如下:
LocationManager locationManager = (LocationManager) Our_app.getAppContext().getSystemService(LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
当GPS_PROVIDER无法获取位置数据时,会检查NETWORK_PROVIDER是否可用并切换:
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
问题挑战
2022年11月23日左右,谷歌或设备厂商推送的更新强制这些设备仅使用省电模式,且无切换至高精度模式的选项。**这导致GPS_PROVIDER和NETWORK_PROVIDER均返回NULL,完全无法获取位置数据!**使用Tecno Go Edition设备的用户因此无法正常工作。
排查过程
尝试启用一段自2017年起注释的旧GPS服务代码,此前因测试发现GoogleApiClient FusedLocation服务的定位精度不足,转而使用硬件GPS,所以将其搁置。
但启用后代码无法正常工作:
using LocationServices.FusedLocationApi.requestLocationUpdates, OnLocationChanged somehow was NEVER CALLED!
经过大量调研,升级到最新的FusedLocationProviderClient:
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(our_app.getAppContext());
但在Oreo及以上系统中启动前台服务时,仅能获取1次位置更新!即使设置了实时模式,onLocationResult也无法持续获取更新:
mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(0); mLocationRequest.setFastestInterval(0); mLocationRequest.setSmallestDisplacement(0); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
问题依旧!
进一步调研发现,由于minSdkVersion为16、targetSdkVersion为31,必须使用PeriodicWorker在后台每秒运行一次,监听onLocationResult并广播坐标,让App其他模块获取最新经纬度。
**最终此方案生效!**另一个问题是何时停止实时更新以避免耗电,通过比较LastKnownLocation精度与当前精度判断:若当前精度小于等于预设最低可接受精度,就停止该Worker,再以更长的GPS间隔和位移重启。
总结
若您发现Android Go设备用户突然无法获取精准位置,可切换至PeriodicWorker并将定位代码放入其中。Stack Overflow上相关提问及示例项目提供了解决思路,在此感谢PRATIK BUTANI!
内容的提问来源于stack exchange,提问作者KuriaNdungu

