记录 uniapp 微信小程序获取定位流程
前言
记录 uniapp 微信小程序获取定位流程。
正文
之前做过一个基于 uniapp 的小程序,当时需要通过定位来获取用户的位置,从而来计算用户所需的运费。
检测 GPS 开关
在手机中,一般都会有一个 GPS 开关,比如我的小米手机是如下这样的:
这个开关决定了所有的应用是否能够使用定位,所以最开始,我们要检测这个开关是否开启了。
在 uniapp 中,有两个可以获取该开关的接口,分别是
第一个 API 里面提示说不推荐使用,所以我们用第二个。
PS:这两个 API 分别对应微信的 wx.getSystemInfo 和 wx.getSystemSetting 。在微信的 wx.getSystemInfo 文档中,有下面这段提示:
从基础库 2.20.1 开始,本接口停止维护,请使用 wx.getSystemSetting、wx.getAppAuthorizeSetting、wx.getDeviceInfo、wx.getWindowInfo、wx.getAppBaseInfo 代替
所以在 uniapp 这边我们用 uni.getSystemSetting 就行了,不过我看文档这个接口只有微信和 APP 支持,但是我在支付宝小程序的文档上发现了相似的接口 my.getSystemSetting,也有这个返回字段,就挺奇怪的😫。
相关代码如下:
1 | const { locationEnabled } = uni.getSystemSetting() |
检测 APP 是否有定位权限
在开启了 GPS 开关之后,我们还要检测微信是否有获取 GPS 的权限,在我的小米中是如下这样的:
这里的话我们要使用 uni.getAppAuthorizeSetting 接口。这个接口返回了 locationAuthorized
,它可以判断微信是否拥有定位权限,代码如下:
1 | const { locationAuthorized } = uni.getAppAuthorizeSetting(); |
检测小程序是否有定位权限
在每个小程序中,都有可以设置是否开启定位权限,比如这里我们拿 BOSS 直聘的小程序,进入小程序后点击右上角的三个点,然后点击设置,出现如下页面:
这里的位置信息就两个选项,一个是关闭,一个是使用小程序时,所以我们要检测的就是小程序的这个选项是不是为“使用小程序时”,这里要使用 uni.getSetting 接口。这个接口返回了 authSetting
对象,这个对象包含了 scope 的信息,其中 scope.userLocation
就是我们需要的值,代码如下:
1 | const { authSetting } = await uni.getSetting(); |
其他的 scope 值可以在上面的链接查看,每个 scope 都会对应某个接口,比如这里的 scope.userLocation
,它对应了 uni.getLocation 和 uni.chooseLocation 接口,这两个接口就是最后我们获取位置信息的。
获取定位信息
在上面的权限全部都符合之后,我们就可以调用 uni.getLocation 来获取当前位置,如果想要别的位置的信息,可以配合 uni.chooseLocation 来实现。
使用 uni.getLocation 的代码如下:
1 | const { |
这里我们用的是 gcj02 的坐标,它和 wgs84 的区别为(摘自 GPT ):
WGS-84(World Geodetic System 1984)
定义
- WGS-84 是一种全球性的地理坐标系,由美国国防部制定,用于 GPS(全球定位系统)。
- 它是一个国际通用的地理参考坐标系。
特点
- 使用地球的椭球体模型描述位置。
- 坐标值是全球统一的,没有针对任何国家或地区的调整。
- 常用于国际场景,例如 GPS 设备、Google Earth 等。
应用场景
- GPS 系统
- 国际地图服务
- 卫星导航与定位
GCJ-02(国测局坐标系)
定义
- GCJ-02 是一种中国国家地理信息系统使用的地理坐标系,由中国国家测绘局开发。
- 它在 WGS-84 基础上进行了加密处理。
特点
- 引入了偏移算法,对 WGS-84 坐标进行一定的随机偏移,以实现加密效果。
- 偏移算法是非线性的,且只有中国政府拥有其完整实现。
- 偏移的目的是为了国家地理信息安全。
- 在中国大陆范围内,WGS-84 坐标会偏离真实位置,偏移量随地理位置变化。
应用场景
- 高德地图、腾讯地图、百度地图(部分基于 GCJ-02)等国内主要地图服务。
- 适用于中国大陆范围的地理位置标注。
简单点讲就是国内就用 gcj02 ,国外就用 wgs84 。
如果不想使用当前的位置,而是手动定位一个位置的话,可以再调用 uni.chooseLocation ,代码如下:
1 | const location = await uni.getLocation({ |
这在微信中会弹出一个微信自带的地图定位选取页面,如下:
缺失权限时的引导
如果用户缺失了某些权限,我们希望能够对用户进行引导,比如提示一段文字,或者如果可以的话,我们可以定位到相应的页面让用户开启某些权限。
缺失全局的 GPS 权限
这种我们只能弹出一个模态框来提示用户开启,模态框可以用 uni.showModal 来创建,相关代码如下:
1 | uni.showModal({ |
这里也可以包在 Promise 中,用起来更加简洁:
1 | await new Promise((resolve) => { |
微信缺失定位权限
这里我们可以使用 uni.showModal 配合 uni.openAppAuthorizeSetting 来让用户进入微信的设置页,代码如下:
1 | const confirm = await new Promise<boolean>((resolve, reject) => { |
小程序缺失定位权限
这里我们可以使用 uni.showModal 配合 uni.openSetting 来让用户进入微信的设置页,代码如下:
1 | const confirm = await new Promise<boolean>((resolve, reject) => { |
后记
当然每个项目需要的定位引导的需求都是不一样,比如我做的那个项目,在用户没有小程序权限时,会引导用户进入小程序的设置页,当从设置页退出的时候,会重新检测一次是否开启,如果没开启,会提示用户功能受限。
当然万变不离其宗,都是上面这些函数组合来组合去而已,熟悉这些步骤后只需要组合即可。