必须配对使用uni.onlocationchange与uni.startlocationupdate,声明requiredprivateinfos和permission权限,手动补全manifest.json,主动申请前后台定位权限,校验精度并节流处理,登录态控制启停,真机调试需基础库≥2.25.0且统一gcj02坐标系。

直接用 uni.onLocationChange + uni.startLocationUpdate 就行,但必须配对使用、必须声明权限、不能跳过初始化检查——漏任何一环,真机上就收不到回调。
manifest.json 必须填满 requiredPrivateInfos 和 permission
微信小程序不认“差不多”,requiredPrivateInfos 里少一个字段,uni.onLocationChange 就永远不触发,控制台也不报错,只静默失效。
-
requiredPrivateInfos至少得包含:"getLocation"、"onLocationChange"、"startLocationUpdate";如果还要后台运行,再加"startLocationUpdateBackground" -
permission下的scope.userLocation和scope.userLocationBackground(后者仅后台需要)都得有独立desc,不能复用文案,比如“用于实时共享您的位置”和“当小程序退到后台时仍需更新位置”必须分开写 - HBuilderX 可视化配置只生成
permission,requiredPrivateInfos得手动补,否则 iOS 真机必返回errCode: -1, errMsg: getLocation:fail privacy permission is not authorized
uni.startLocationUpdate 调用前必须先检查并申请权限
很多人以为调了 uni.getSetting 看到已授权就直接开监听,结果在 Android 厂商定制系统(华为、小米)上失败——因为 scope.userLocationBackground 权限可能被系统藏在「电池优化白名单」里,前端无法弹窗申请。
- 必须用
uni.authorize({scope: 'scope.userLocation'})主动触发前台权限申请;后台权限同理,且要单独调一次uni.authorize({scope: 'scope.userLocationBackground'}) -
uni.getSetting返回authSetting['scope.userLocationBackground'] === true≠ 实际可用,得配合uni.startLocationUpdateBackground的fail回调做兜底重试 - iOS 上首次调
startLocationUpdateBackground即使用户点了“始终允许”,也可能返回fail: system permission denied,建议加 1~2 秒延迟后重试
onLocationChange 回调不是实时推送,得靠精度和节流过滤
uni.onLocationChange 是系统级事件,只在位置发生“显著变化”时触发,不是每秒一次。实际收到的坐标可能抖动大、精度低、间隔长(首次回调常延迟 5~15 秒),直接存或传给业务逻辑容易出错。
- 务必检查
res.accuracy,建议只接受accuracy 的坐标(30 米内才算可靠) - 自己实现简单节流:记录上一次有效上传时间戳,两次有效坐标间隔至少 10 秒再触发业务(比如上传、刷新距离),避免高频无效请求
- 别依赖
res.city或res.street字段——微信原生只在部分平台(如百度小程序)返回这些,小程序端基本为空,地址解析必须走高德/腾讯服务端 API
登录态控制是关键开关,别让未登录用户持续定位
定位不是越勤快越好。未登录用户开启 uni.startLocationUpdate,既耗电又违规(违反 GDPR 和国内《个人信息保护法》的数据最小化原则)。
- 监听启动逻辑必须包裹在登录检查之后:先读
uni.getStorageSync('token'),再验证有效性(比如对比expires_at),确认登录态才调startLocationUpdate - 退出登录时,必须显式调用
uni.stopLocationUpdate()并移除uni.onLocationChange监听(用闭包函数或全局变量保存回调引用) - App 全局状态管理推荐放在
app.vue的onShow/onHide生命周期里统一调度,避免多个页面重复启停导致状态错乱
最易被忽略的是:微信开发者工具模拟器不支持 onLocationChange 后台行为,真机调试时必须关掉「调试基础库版本」自动降级,确保基础库 ≥ 2.25.0;另外,uni.getLocation 默认返回 GCJ02 坐标,但 onLocationChange 不受 type 参数影响,始终是 GCJ02,前后端坐标系必须对齐,否则地图打点偏移几百米。










