H5获取地理位置?不容易!

H5作为未来的趋势已然新增了很多很强大的功能,其中获取设备GPS信息更是强化了H5在手机网页应用的地位。甚至在获取数据的方法上也相当简单,无需复杂的配置只需在JavaScript中简单地调用一下函数。

navigator.geolocation.getCurrentPosition(success, error, options)

看上去好像很美好的样子,但其实内里有着很多不可预料的坑在一一等着我们去解决。其中笔者在实际使用过程中发现 Android大部分机型会存在获取地理位置超时 的情况。

国行机型,用户之殇

当我第一次知道要获取地理位置的时候,其实我是,是拒绝的,我跟产品讲,我拒绝,因为,其实Android有问题。好了,卖了下萌,回归正题!

一开始搜遍stackoverflow和google groups给出的答案就是试试连上WIFI、试试重启之类无关痛痒的问题。只要是非中文的答案都找不出解决方案,后来发现其实是国行Android由于被阉割了谷歌的GMS服务,导致能正常调用 getCurrentPosition 函数但永远无法触发回调。

在经过测试后,发现部分国内厂商的浏览器对 getCurrentPosition 进行了重新的封装,其中UC、QQ浏览器都已经重新封装了但对于国际大厂的浏览器由于没有考虑到我国特殊情况所以一律都超时。

解决方案

无奈地友情提示

大部分智能手机都能很好的支持 getCurrentPosition ,但鉴于上面提及的特殊问题我们仍需要判断一下并作出一些提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(pos) {
// A callback function that takes a Position object as its sole input parameter.
// 成功回调函数,接受一个地理位置的对象作为参数。
// https://developer.mozilla.org/en-US/docs/Web/API/Position 参数说明
}, function(err) {
// An optional callback function that takes a PositionError object as its sole input parameter.
// 错误的回调
// https://developer.mozilla.org/en-US/docs/Web/API/PositionError 错误参数
}, {
enableHighAccuracy: true, // 是否获取高精度结果
timeout: 5000, //超时,毫秒
maximumAge: 0 //可以接受多少毫秒的缓存位置
// 详细说明 https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions
});
} else {
alert('抱歉!您的浏览器无法使用地位功能');
}

通过以上代码,可以对不支持 getCurrentPosition 机器作出友好的提示。根据查阅 PositionError 可以得知被阉割GMS模块的Android返回的错误码2或者3。

百度地图的黑魔法

在实验过程中,笔者在同款浏览器下查看了百度地图令笔者惊讶的是那个小图标屹立在我们的办公区内。但经过各种测试发现其实只是利用了WIFI的IP定位,最终发现只是封装了一下H5原生的geolocation,被阉割的还是被阉割的终究没法完成定位。

不过百度地图提供的API更为丰富,其中包括了:根据IP定位城市、根据地方名返回坐标等等。

总结

感觉没什么好总结的,这个让我想起了最近支付宝一直被轰说苹果婊,但有时候真的百般无奈。系统被阉割、不完善等不可抗力的原因这个能怪谁?而且有时候问题太特殊了……默哀,为安卓、WinPhone的用户。