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
相关推荐
andrsted1 天前
作业发布、课堂检测和错题讲评,用一个小程序完成
学习·微信小程序·小程序·学习方法
汤姆yu1 天前
基于微信小程序的家电维修预约系统
微信小程序·小程序·家电维修
软件聚导航2 天前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
一叶星殇2 天前
微信小程序 Vant Popup 滚动穿透:页面级与组件级解决方案详解
微信小程序·小程序
2601_963869952 天前
【计算机毕业设计】基于微信小程序的点餐传菜系统设计与实现
微信小程序·小程序·课程设计
北漂燕郊杨哥2 天前
VS Code 安装微信小程序 MCP 介绍
vscode·微信小程序·小程序·mcp
维双云3 天前
2026微信小程序开店用哪个平台?长期稳定运营的系统选择方法
微信小程序·小程序
辛迪聊物业数字化3 天前
【智能楼宇系统有什么用?赋能园区高效 节能 安全】
经验分享·安全·微信小程序·php
Coodor3 天前
使用web也可以写NFC微信小程序拉取
前端·微信小程序·小程序·nfc拉起小程序
太阳之神aboluo4 天前
微信小程序 (1) 基础用法
微信小程序·小程序