业务中做了一个签到的功能,需要在调用签到接口前,调用一个是否在签到范围的接口,需要传入经纬度参数,本文讲解下,如何在 uniapp 微信小程序中获取位置信息并完成这一业务需求。
小程序管理后台配置:
- 进入「开发」->「开发管理」->「开发设置」
- 在「接口设置」中确保「地理位置」接口已开启
服务器域名配置(如果需要将位置信息发送到服务器):
- 在「开发设置」->「服务器域名」中配置合法域名
manifest.json配置(必须)
在 项目 的 manifest.json 文件中添加以下配置:
{
"mp-weixin": {
"appid": "你的小程序ID",
"requiredPrivateInfos": ["getLocation"],
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序定位服务"
}
}
}
}
代码实现
获取地理位置的 api 为 wx.getLocation,使用起来比较简单,但是我们却不能仅仅只调用这个接口,还需要经过以下前置的操作才能完成一个完整的获取地理位置行为。
1. 调用wx.getSetting
wx.getSetting 用于查询用户已经授予的权限状态,返回结果包含所有已请求过的权限的授权状态(如位置、相册、用户信息等)。
典型场景:
- 检查用户是否已经授权过某个权限
- 避免重复弹窗请求授权(提升用户体验)
- 获取完整的权限设置情况
2. 调用wx.authorize
wx.authorize 直接向用户发起授权请求弹窗,如果用户之前已经授权或拒绝过,行为会有所不同:
- 首次请求:弹出授权窗口
- 用户之前同意过:静默成功
- 用户之前拒绝过:直接失败(必须通过
wx.openSetting引导用户手动开启)
当完成上述的两个流程,才能去调用wx.getLocation方法,因为这几个函数调用成功后都是返回的回调函数,嵌套的调用看起来比较不清晰,因为我只需要地理位置信息,所以我就封装了一个方法,来实现上述三个操作,最终只返回地理位置信息,完整代码如下:
getLocation() {
function fetchAuthorize() {
function showTipModal() {
wx.showModal({
title: "提示",
content: "系统需要获取该您当前的定位,请确保您的位置授权已开启",
showCancel: false,
success: (res) => {
if (res.confirm) {
wx.openSetting();
}
},
});
}
return new Promise((resolve, reject) => {
wx.authorize({
scope: "scope.userLocation",
success: (res) => {
console.log("授权成功");
resolve(true);
},
fail: (res) => {
console.log("授权失败", res);
showTipModal();
},
});
});
}
function fetchLocation() {
return new Promise((resolve, reject) => {
wx.getLocation({
type: "gcj02",
success: (res) => {
console.log("获取位置成功", res);
resolve(res);
},
fail: (res) => {
console.log("获取位置失败", res);
reject(res);
},
});
});
}
return new Promise((resolve, reject) => {
// 1. 先检查权限状态
wx.getSetting({
success: async (res) => {
if (res.authSetting["scope.userLocation"] === undefined) {
// 2. 用户从未请求过:直接调用授权
await fetchAuthorize();
const location = await fetchLocation();
resolve(location);
} else if (res.authSetting["scope.userLocation"] === false) {
// 3. 用户拒绝过:引导去设置页
showTipModal();
} else {
// 4. 用户已授权:直接使用
const location = await fetchLocation();
resolve(location);
}
},
fail: (res) => {
console.log("获取权限状态失败", res);
reject(res);
},
});
});
}
getLocation这个方法,返回一个 promise,其结果就是wx.getLocation返回的位置信息,实际调用的时候就可以通过同步函数来拿到位置信息:
async checkPosition() {
const { latitude, longitude } = await this.getLocation();
request({ latitude, longitude } )...
}