uniapp微信小程序获取地理位置解决方案

677 阅读3分钟

业务中做了一个签到的功能,需要在调用签到接口前,调用一个是否在签到范围的接口,需要传入经纬度参数,本文讲解下,如何在 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 } )...
}