问题描述
- cordova页面中使用高德地图js api AMap.Geolocation的geolocation.getCurrentPosition()方法进行定位
- 用手机4g打开该页面,定位失败,返回错误信息:Get ipLocation failed.
- 手机连接wifi后,正常定位
分析
关于高德地图的定位逻辑,可以参考:
官方链接:Geolocation的定位流程以及定位失败的原因?
可以看到,其顺序是:
sdk辅助定位
浏览器原生定位接口
精确ip定位
这三种方式非常重要,后面我们的解决方案是基于此的
在wifi情况下,其定位通过抓包可以看到其使用的是ip定位,其实是比较慢的,而且既然其使用了ip定位,那么说明其前面两种方式没有成功。
对于sdk辅助定位,可以参考官方文档:新版辅助H5页面定位
这个是要求服务端和js使用端都要做相关配置的,这个在我们直接使用的情况下(服务端没有配置)是不生效的
那么问题来了,为什么浏览器原生定位接口失败了呢?
浏览器H5是可以通过navigator.location.getCurrentLocation来获取当前位置的,但是我们在我们的工程中直接使用此方法,发现如果加了超时时间,其会报错:message: Timeout expired。如果没有加超时时间,其会报错:Geolocation has been disabled in this document by Feature Policy.
尝试着就这两个错误(主要是后面这个错误)进行解决,无果。
于是邀请了android同事来查看问题,android同事果然专业,上来就提议一起看cordova的源码,debug进去。一进去果然发现了问题:
navigator.location.getCurrentLocation其会调用cordova-plugin-geolocation的geolocation.js中的getCurrentLocation方法,但是其src中的execute方法仅仅是处理了permission相关的东西,并没有进行任何实质意义上的定位。这个就很奇怪了。代码贴出来看一下
geolocation.js
看起来似乎是个死循环的调用,看不懂了
总之,就我们目前的技术水平,觉得浏览器原生定位接口这条路走不通了,不知道这是不是cordova某个版本下的一个问题
当然高德地图官方也说明了浏览器定位失败是有很多原因的
第一个问题没有解决,来看第二个问题:
wifi情况下通过精确ip定位定位成功,这还比较不错
但4g下,至少我们几个人的手机都是精确ip定位失败,100%的失败率,报错:Get ipLocation failed
高德官方的说法:
难道第二个问题也不解决了,任其如此了?
这个时候android的同事把目光投到了我们前面说的sdk辅助定位上。那问题三又来了,这个服务端哪里来呢?既然官方的cordova-plugin-geolocation不好用,那么有没有第三方的plugin呢?来到github,果然被发现了
https://github.com/ergoli/cordova-amap-location
直接src进去看了一下,完美的代码
这样就按照其介绍的方式,在高德开发者申请了android的key,生成sha1值。配好后果然可用,而且定位速度很快。
结论
1. 我的这位android同事厉害
2. 官方文档真的是要认真读,认真思考