uni.getLocation()和uni.openSetting()

文章目录

环境

  • Windows 11 专业版
  • HBuilder X 4.65
  • 微信开发者工具 Stable 1.06.2412050

背景

在小程序开发中,需要用户授权地址位置信息,以获取当前的经纬度,从而进一步获取省市等地理信息。

可通过两种方法来让用户授权:

  • uni.getLocation()
  • uni.openSetting()

前者界面如下:

后者界面如下:

关于二者的区别和联系,后面会有详细介绍。

问题

在调用 uni.getLocation() 时,并没有弹出对话框,而是报错了:

powershell 复制代码
"getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json"

然后在调用 uni.openSetting() 时,在设置页面里,也并没有"位置消息",只有"订阅消息":

分析

这其实是两个问题。

问题1

调用 uni.getLocation() 时报错。

这个错误是因为微信小程序要求从2022年起,部分敏感接口(如 getLocation )必须在 app.json / ext.jsonrequiredPrivateInfos 字段中声明才能调用,否则会报错。

对于UniApp项目,则需要修改 manifest.json 文件。

在该文件的 "mp-weixin" 下面,添加 requiredPrivateInfos 信息如下:

javascript 复制代码
    "mp-weixin" : {
    ......
        "requiredPrivateInfos": ["getLocation"],
        "permission" : {
            "scope.userLocation" : {
                "desc" : "你的位置信息将用于小程序位置接口的效果展示"
            }
        }
    },
    ......

注:这里的 desc ,就是弹出对话框时的描述信息。

完整代码如下:

javascript 复制代码
// 获取地理位置
uni.getLocation({
  type: 'wgs84',
  success: (res) => {
    console.log("位置获取成功:", res.latitude, res.longitude);
  },
  fail: (err) => {
    console.error("获取位置失败:", err);
    if (err.errMsg.includes("permission")) {
      // 引导用户授权
      uni.showModal({
        title: '权限提示',
        content: '需要地理位置权限才能继续',
        success: (modalRes) => {
          if (modalRes.confirm) {
            uni.openSetting();  // 跳转设置页
          }
        }
      });
    }
  }
});

问题2

调用 uni.openSetting() 时没有"位置消息"。

这是因为,微信小程序的设置页默认只显示已申请过的权限。比如说,用户之前拒绝过地理位置权限,那么设置页就会显示该选项。

那么问题来了,前面不是明明已经调用了 uni.getLocation() ,为什么还说没有申请过权限呢?原因很简单,因为调用 uni.getLocation() 报错了,并没有成功。

因此,把问题1解决后,问题2就迎刃而解了。

uni.getLocation()和uni.openSetting()的区别和联系

从前面的代码中我们看到,先是调用 uni.getLocation() ,如果fail了,就再调用 uni.openSetting() ,这是为什么呢?两者不都是授权吗?既然 uni.getLocation()已经被用户拒绝了,为什么还要通过 uni.openSetting() 让用户手工设置呢?

这主要是因为小程序有一个"静默期"机制,目的是防止开发者频繁骚扰用户。如果第一次调用 uni.getLocation() 时,用户选择了拒绝,后面再调用时就不再弹框了。

具体说来,当用户第一次调用 uni.getLocation() 时,系统会弹窗询问权限,用户可以选择允许或者拒绝。

  • 允许:则下次调用 uni.getLocation() 时,不再弹窗,直接获取用户地理位置信息。
  • 拒绝:同理,下次调用 uni.getLocation() 时,不再弹窗,直接失败(静默期通常持续几分钟到几小时,具体由微信控制)

在静默期,唯一能让用户重新开启权限的方式就是,引导用户主动进入设置页(openSetting)手动开启权限:

  • 设置页是用户主动操作进入的(非自动弹窗),不受静默期限制
  • 用户可能误点拒绝,需要提供明确的修正入口

当然,用户在静默期也可以直接去手机的权限设置里去设置权限,不过通过引导用户主动进入设置页,显然对于用户来说会有更好的体验。

此外,从前面代码中可见,是先调用 uni.showModal() 弹出对话框,如果用户选择"确定",才调用 uni.openSetting() 跳转设置页。也就是说,对于敏感权限,必须用户显式触发,才能去设置。这里可能不能直接设置,不过我没有验证过。

其它

uni.getLocation()的fail

uni.getLocation() 有两个回调方法,分别对应 seccessfail 。缺少 requiredPrivateInfos 报错,以及点击"拒绝"按钮,都会触发 fail 回调,但是二者的error不一样:

  • 缺少 requiredPrivateInfos"getLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json"
  • 点击"拒绝"按钮: "getLocation:fail auth deny"

必要时,可通过error内容来判断fail的原因。

uni.openSetting()的authSetting对象

在从 uni.openSetting() 获取用户配置的位置消息时,其 success 回调包含了response参数,该参数包含了 authSetting 对象。通过该对象的 scope.userLocation 属性来判断用户对位置消息的设置值,其中true表示允许,false表示不允许:

但要注意,如果页面上没有位置消息的设置,则authSetting里也就不包含 scope.userLocation 属性。如果尝试获取,则获取到的是 undefined

参考

  • https://uniapp.dcloud.net.cn/api/location/location.html#getlocation
  • https://uniapp.dcloud.net.cn/api/other/setting.html#opensetting
相关推荐
番茄Salad2 小时前
微信小程序中,解决lottie动画在真机不显示的问题
微信小程序·小程序
wx_cxc28486989184 小时前
羽毛球订场小程序源码介绍
微信小程序·小程序
wx_cxc284869891815 小时前
物业后勤小程序源码介绍
微信小程序·小程序
abigale0319 小时前
【b站计算机拓荒者】【2025】微信小程序开发教程 - 3 项目目录结构
微信小程序·小程序
砂川同学1 天前
STM32+ESP8266+ONENET+微信小程序上传数据下发指令避坑指南
stm32·嵌入式硬件·微信小程序
ywyy67981 天前
微小店推客系统开发:构建全民营销矩阵,解锁流量增长密码
人工智能·搜索引擎·微信小程序·系统·短剧·推客系统·微小店
老李不敲代码2 天前
榕壹云上门家政系统:基于Spring Boot+MySQL+UniApp的全能解决方案
spring boot·mysql·微信小程序·小程序·uni-app
ywyy67983 天前
推客小程序系统开发:全栈式技术解决方案与行业赋能实践
大数据·人工智能·微信小程序·小程序·系统·推客系统·推客小程序
ywyy67983 天前
「数智化聚合分销生态系统」定制开发:重构全渠道增长引擎
大数据·搜索引擎·微信小程序·小程序·系统·聚合分销系统·聚合分销