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
相关推荐
咖啡の猫16 小时前
微信小程序案例 - 自定义 tabBar
微信小程序·小程序·notepad++
咖啡の猫17 小时前
微信小程序全局数据共享
微信小程序·小程序
桐溪漂流17 小时前
微信小程序cli脚本预览上传
微信小程序·小程序
咖啡の猫17 小时前
微信小程序使用 npm 包
微信小程序·小程序·npm
东东5161 天前
xxx食堂移动预约点餐系统 (springboot+微信小程序)
spring boot·微信小程序·小程序·毕业设计·个人开发·毕设
韩立学长2 天前
【开题答辩实录分享】以《智慧校园平台微信小程序》为例进行选题答辩实录分享
spring boot·微信小程序·小程序
h_65432102 天前
微信小程序:按顺序一张图片加载完后,再加载另一张
微信小程序·小程序
qq_316837753 天前
uniapp打包微信小程序使用插件
微信小程序·小程序·uni-app
不爱学习小趴菜4 天前
uniapp微信小程序无法屏蔽右上角胶囊按钮(...)问题解决方案
微信小程序·小程序·uni-app
plmm烟酒僧4 天前
《微信小程序demo开发》第一部分-编写页面逻辑
javascript·微信小程序·小程序·html·微信开发者工具·小程序开发