最近工作中遇到了一个涉及后台持续性定位的问题。这里做一下总结:随着Android版本的条件,Google对后台服务管控的也是越来越严格。 这时有的小伙伴会说了,开启一个service然后把服务和通知关联一下变成前台服务,不就行了!这样做的话,只要app不被手动的销毁,前台服务会一直存活。没错,确实是这样!
我们在前台服务中引入定位功能后,定位间隔3s一次,通过日志打印,不管我们是挂起app或者手机锁屏,定位日志都会一直打印。到这里我们会觉得没什么问题呀,这不挺正常的嘛!
可是有过此类似经验的小伙伴会知道,虽然会一直定位,但是定位的坐标发生了变化(偏移)。app长时间后台挂起或者锁屏,第三方sdk(百度,高德)的定位服务,出现了严重定位偏差。发现此问题后,分别查阅了百度和高德开发文档,相关资料如下:
百度地图文档
高德文档
分别尝试了文档中的方法,很遗憾仍然未能解决长时间后台挂起或者锁屏,出现定位偏差问题。
再次查阅资料,发现由于手机厂商电池优化等原因,限制了锁屏后定位,联网等操作。小米手机截图:
当我尝试选择 无限制 选项后,是的,和你预想的一样,不管app挂起时间有多长,锁屏时间有多长,app都能 精度 很高的进行定位,再没有出现定位偏差。说到定位精度,我们不得不提一下这个参数,百度或者高德地图定位成功后,除了返回坐标还有定位精度这个关键参数。此值越小说明定位精度越高,也就是定位越准确。
来来来,我们不要扯太远,哈哈。
这时有的小伙伴会说了,这种方法看着确实不错,但是不同手机厂商界面应该是不一样的吧,那我们通过什么方法,引导用户跳转到这个界面让用户选择呢?
方法如下:
1:判断是否已打开省电策略白名单
@RequiresApi(api = Build.VERSION_CODES.M)
public boolean isIgnoring(Activity activity) {
boolean isIgonring = false;
PowerManager manager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
if (null != manager) {
isIgonring = manager.isIgnoringBatteryOptimizations(activity.getPackageName());
}
return isIgonring;
}
2:弹出打开省电策略白名单的选项,确定就好了
public void goSetting(Context mContext) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);//ACTION_APPLICATION_DETAILS_SETTINGS
Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
intent.setData(uri);
mContext.startActivity(intent);
}
注意:小米手机亲测可以跳转到设置界面,其他机型并未亲测。
放到最后想说的话:相信很多小伙伴看过不少app保活文章,有说双进程,双服务相互拉起保活的,有说1个像素点保活的,有说系统白名单,有说定时唤醒CPU的等等。建议大家还是不要耗费太多精力在这方法的研究上,试想一下,如果所有的Android开发人员都去这样做,都想保活自家的app,会是一个什么样的生态圈。Android系统会永远不如苹果系统流畅和省电等。如果我是一家安卓手机厂商的负责人,也会通过不同的手段去遏制此类事情发生。
参考文章:
关于使用系统定位持续后台定位的一点心得
android定位权限适配看这篇就够了
BDLocation