艺灵设计

全部文章
×

uni-app跨端开发微信小程序之打包成H5后加载缓慢、定位不准到底是怎么回事?

作者:艺灵设计 - 来源:http://www.yilingsj.com - 发布时间:2020-10-05 15:49:53 - 阅: - 评:0 - 积分:0

摘要:在微信小程序端,通过调用wx.chooseLocation这个API可以快速实现定位和搜索的功能。但到了微信公众号中,事情远比想像的要复杂的多。无论是腾讯地图还是高德地图还是百度地图,都存在定位不准的问题。除去各家自身的因素,定位不准最核心的原因就是:用户没有授权!除此之外,在获取经纬度时需要注意使用gcj02火星坐标而不要使用默认的wgs84......

在开发上一个生鲜类小程序时之所以选择uni-app而不是原生开发是因为我们还有微信公众号版!公众号不就是H5嘛,再看看uni-app的官方描述,用它,没错了!

但事实证明,在开发过程中仍有许多坑需要自己填......

一、地图加载异常

在上一节的内容里,我通过调用wx.chooseLocation这个API来实现地图定位、搜索的功能。在微信小程序中一切正常,但打包成H5后就异常了。当时测了5台安卓机,3台苹果机,出现的现象是:苹果机秒开地图且定位准确,部分安卓机秒开地图定位准确,部分安卓机打开地图需要10以上且定位不准!测完我就懵圈了......

当时搞了好久也没找出原因,同事说公众号里要用微信的jssdk。然后我在微信开发文档中找到了wx.openLocationwx.getLocation,但没有看到wx.chooseLocation戳我访问微信文档:地理位置。莫非微信公众号中不支持?带着疑问,我单独创建一个demo进行地图专测。

直接测不行呀,因为要配置wx.configSSL,然后又让后端老哥把域名配置SSL并提供了一个获取wx.config所需参数的的接口。一切准备工作完毕后,我以为本地就能跑了。结果发现本地跑不了,要传到线上才能跑。然后我又要来了宝塔帐号,自己改自己传,最终线上的demo页面终于跑通了。然后我在控制台输入wx.getLocation后有反应,输入wx.chooseLocation后输出undefined。如图:微信sdk中没有wx.chooseLocation这个方法.png动态导航已经成功添加到页面上什么情况?没有??那么问题来了:为什么苹果手机就能正常显示呢?而且部分安卓机也可以,部分安卓机不行,这到底是怎么回事??是uni-app在打包时自己做了处理吗???

一连串的问号没法解决,当务之下,只好换方法喽。由于凯哥说后面还要嵌入到App中,所以要选一家定位准的地图,最后大家一波吐槽讨论过后,一致选择了高德地图。于是,我又开始了填坑之路......

二、条件编译后定位时准时不准到底是个什么鬼?

uni-app提供了条件编译,所以这里我们就可以根据不同平台使用对应的方法来实现兼容。比如:在微信小程序中,我们使用wx.chooseLocation,在H5中,我们使用高德地图。

话说起来容易,但做起来难啊!最后,我被这个地图折磨了一个星期,事后我也反思了下,自己太过于极端情况的考虑了。但事实上可能就会有这样的用户呀,如果在开发期间我自己对极端情况都不了解的话,产品上线了,用户找来了,我拿什么给人家解释?难不成我说:别人手机都没问题,就你手机有问题,手机该换了?RP问题?这用户要是在现场不得把我一顿爆锤呀!

2.1、无数次的折磨过后发现授权弹窗的规律

极端情况什么意思呢?上一篇提到过用户拒绝授权一事,在H5端也是存在这种情况的,而且不同的手机、用不同的浏览器打开也是不一样的!最后我发现的规律是:在苹果手机上,用微信打开链接,24小时内拒绝定位授权超过3次,则在24小时内无法再唤醒授权,超过24小时后刷新页面会继续提醒授权。在安卓手机上,用微信打开链接,安卓机中弹窗中的是“取消”而不是“不允许”或“拒绝”,所以,安卓机微信上可以一直弹窗,直到用户同意为止。对于浏览器而言,不同的浏览器上弹窗中的按钮也是不同的,一般出现“拒绝”的,只需要点一次,无论怎么刷新浏览器或清空浏览器的缓存都无法再唤醒授权的弹窗!但有的浏览器可以通过在设置中清除来实现继续显示弹窗授权。如图:在苹果手机和安卓手机上的弹窗有所不同.png在苹果手机和安卓手机上的弹窗有所不同
在某浏览器上弹窗授权显示拒绝或允许.png在某浏览器上弹窗授权显示拒绝或允许

说到这里可能有看官要问了,为什么你老纠结于这个授权的弹窗啊!

2.2、为什么要在意授权的弹窗?

原因是这样的:不管是使用腾讯提供的sdk还是使用高德地图,都需要先获取用户的经纬度,即使你使用别人家的地图通过定位的方式。而获取经纬度就需要用户授权,用户拒绝了授权后,由于获取不到经纬度,所以地图功能无法正常使用。即使使用了,也会出现定位不准的情况!这就是最后我用苹果手机测试时发现苹果手机定位不准安卓机反而准的原因。还有一个原因就是:用户手动拒绝或手动关闭系统定位,我是不知道的,第三方提供的API接口也检测不到,他只能检测到获取不到经纬度。如果用户开启了系统定位并拒绝了授权,难道我还要继续提示用户开启系统定位??这用户不得说你产品有Bug啊!!!所以,我有多难,你们能想像的到吗?

也正是因为这个问题的存在,导致我时常在测试时发现时准时不准。具体来说就是:明明苹果机昨天还是定位准确的啊,怎么今天就不行了?之前是部分安卓机定位不正常,怎么现在出现之前定位正常的现在不正常了,之前不正常的现在正常了,这到底是什么鬼???

......

2.3、当用户同意了授权,为什么有的手机定位准,有的手机定位不准?

在后面的测试期间,我一共用了10台手机做测试,4台苹果6台安卓。然后我就发现一个奇怪的现象:
部分安卓机只开wifi时,就能实现精准定位;部分安卓机要开流量+定位时才行,单开流量不开定位时定位不准。另一个影响定位准确的因素是:我在获取经纬度时使用了默认的wgs84而不是gcj02 火星坐标,所以后面我全改成了gcj02。微信公众号开发文档中默认给出的就是wgs84,看官需要注意。

2.4、使用高德的 AMap.Geolocation 就准确吗?

来个小插曲。之前由于不知道是什么原因导致为什么有的手机定位准有的手机定位不准,所以我也换了很多个方法,基本上我把高德提供定位的几种方法试遍了。比如:高德的AMap.Geolocation虽然不需要获取用户的经纬度就能定位,但也需要用户授权同意才行啊!如果在苹果机上拒绝了,那再用苹果机打开地图时就不准了。这也就是我前面说的,明明我的苹果机前一天还是好的,怎么过了一夜就不好了的原因。

2.5、最后总结

大致如下:
1、不管是微信的sdk还是高德的地图,必须要先配置好SSL证书;
2、确保入口的链接是https而不是http(小心公众号的入口未改成https)
3、不管是微信的sdk还是通过浏览器实现定位,在弹出授权时若苹果机用户拒绝了3次,在24小时内无法再唤醒授权;
4、通过wx.getLocation获取经纬度时要修改成gcj02火星坐标!

2.6、demo演示

最后,啥也不多说了,说多了都是泪!献上自己测试期间写的demo,效果如图:demo界面.pngdemo界面
有兴趣的看官可以扫码访问,注意要用微信扫码哈。二维码:测试期间做的demo(不保证此demo链接可永久访问)

三、抛开权限,如何使用高德地图实现一个带搜索+定位的功能?

虽然微信的jssdk中提供了wx.openLocation可以直接打开地图的功能,但比起小程序里面的wx.chooseLocation,无论是从界面还是功能,都有所差别。再说了,为了样式和功能尽可能与小程序统一,所以这里我们要自己实现一个界面和功能像wx.chooseLocation 的地图。

3.1、方案一:高德选址组件

在高德地图官方文档中,提供了选址组件的功能,戳我访问官方文档,界面如图:高德地图提供的选址组件.png高德地图提供的选址组件怎么样,搜索、定位、当前位置、地址列表4种功能全部都有,这完全就是我们想要的嘛!只不过样式跟微信小程序中的差距略大,但功能上完全能接受。说到这里,看官是不是有点兴奋了?别急别急,细心的你会发现左上角有一个返回按钮,经过测试发现这个按钮根本就是个摆设!

这时可能有看官要说了,那你去掉或加个返回的事件不就完了呗!

一个个站着说话不腰疼,我们来看看高德的选址组件如何调用吧,代码如下。

  1. <iframe src="https://m.amap.com/picker/?center=经度,纬度&key=你的key" frameborder="0" id="iframe" class="map_container"></iframe>

什么?iframe???

是的,你没有看错,是一个iframe,只需要传入经纬度和申请的key即可。

由于是iframe且页面域名不受我们控制,所以里面的东西自然不能随便改造,顶多只能监听其提供的一些方法罢了。那要怎么办呢?这个返回按钮放这时,用户点击没反应,用户肯定以为这是Bug啊!

3.1.1、css搞定返回按钮

这个时候css可能登场了,我们可以给iframe添加一个父级并设置相对定位,然后再用一个36*36的透明盒子遮挡住这个按钮,最后给这个透明的盒子添加js事件,点击时返回上一页即可搞定需求!

  1. <div class="iframe-wrap">
  2.   <iframe src="https://m.amap.com/picker/?center=经度,纬度&key=你的key" frameborder="0" id="iframe" class="map_container"></iframe>
  3.   <div class="back"></div>
  4. </div>

3.2、方案二:逆地理编码 + POI搜索 + 输入提示 + 拖拽定位

从功能实现上来说,使用iframe是最简单的了,但如果对UI有洁癖的话,我们可以采用方案二:逆地理编码 + POI搜索 + 输入提示 + 拖拽定位。也就是自己通过高德地图提供的一系列功能中,抽取我们需要的一些来实现需求。这种方式会让我们对UI界面有更大的把控,同时也会加大我们实现功能的时间。

3.3、方案三:浏览器定位(AMap.Geolocation) + POI搜索 + 输入提示 + 拖拽定位

这种方法跟上一种差不多,但区别在于:前者必须要手动传入经纬度,而后者不需要手动传统经纬度。最终效果如图:高德地图浏览器AMap.Geolocation定位.png高德地图浏览器AMap.Geolocation定位

其他的方式我没有进行测试,反正不管是用哪一种方式,前提条件必须是:用户必须要授权位置权限,否则定位都是不准确的!!!

四、源码下载

最近时间有点儿紧,先空着,晚点儿提供。

转载声明:
  若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:http://www.yilingsj.com/xwzj/2020-10-05/uni-app-h5-getLocation.html

若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。

亲,扫个码支持一下艺灵呗~
如果您觉得本文的内容对您有所帮助,您可以用支付宝打赏下艺灵哦!

Tag: uni-app 微信小程序 跨端开发 wx.chooseLocation wx.openLocation wx.getLocation jssdk AMap.Geolocation 高德地图 POI gcj02 wgs84

上一篇: uni-app跨端开发微信小程序之wx.chooseLocation打开地图并实现定位功能   下一篇: uni-app跨端开发之微信公众号中调用分享sdk时成功但无法唤醒分享的弹窗?

评论区