乐于分享
好东西不私藏

小程序地理位置授权-uniapp实现

小程序地理位置授权-uniapp实现

适用场景
1. 地图导航:获取用户当前位置,提供导航服务
2. 附近服务:推荐附近的商家、景点、服务设施等
3. 位置分享:分享用户当前位置给好友
4. 打卡签到:基于位置的打卡签到功能
5. 天气服务:根据用户位置提供当地天气信息
6. 物流追踪:基于位置的物流信息查询
权限类型
权限名称
描述
对应接口
scope.userLocation
获取当前位置
uni.getLocation, uni.chooseLocation
scope.userLocationBackground
后台定位
uni.startLocationUpdateBackground
权限申请方式
// 申请地理位置权限async function requestLocationPermission() {  try {    const res = await uni.getSetting({      success(res) => {        if (!res.authSetting['scope.userLocation']) {          uni.authorize({            scope'scope.userLocation',            success() => {              console.log('授权成功');            },            fail(err) => {              console.log('授权失败', err);            }          });        }      }    });  } catch (error) {    console.log('获取设置失败', error);  }}
实现案例
<checkboxv-model="agreePrivacy" /><button @click="getCurrentLocation"type="primary"class="btn">    获取当前位置</button><button @click="chooseLocation"type="primary"class="btn">    选择位置</button>
// 显示隐私协议showPrivacy() {    uni.navigateTo({    url'/pages/agreement/privacy'    });},// 获取当前位置async getCurrentLocation() {    if (!this.agreePrivacy) {      uni.showToast({        title'请先阅读并同意隐私协议',        icon'none'      });      return;    }    try {      // 检查权限      const settingRes = await uni.getSetting();      if (!settingRes.authSetting['scope.userLocation']) {        // 申请权限        try {          await uni.authorize({            scope'scope.userLocation'          });        } catch (authError) {          // 授权失败,引导用户去设置页面          this.guideUserToOpenPermission();          return;        }    }    // 获取位置    uni.showLoading({ title'定位中...' });    uni.getLocation({        type'wgs84',        altitudetrue,        success(res) => {          uni.hideLoading();          this.locationResult = res;          uni.showToast({            title'定位成功',            icon'success'          });        },        fail(err) => {          uni.hideLoading();          this.handleLocationError(err);        }    });    } catch (error) {      uni.hideLoading();      console.log('获取位置失败', error);      uni.showToast({        title'获取位置失败,请稍后重试',        icon'none'      });    }},// 选择位置async chooseLocation() {    if (!this.agreePrivacy) {      uni.showToast({        title'请先阅读并同意隐私协议',        icon'none'      });      return;    }    try {      // 检查权限      const settingRes = await uni.getSetting();      if (!settingRes.authSetting['scope.userLocation']) {        // 申请权限        try {          await uni.authorize({            scope'scope.userLocation'          });        } catch (authError) {          // 授权失败,引导用户去设置页面          this.guideUserToOpenPermission();          return;        }    }    // 选择位置    uni.chooseLocation({        success(res) => {          this.locationResult = res;          uni.showToast({            title'选择位置成功',            icon'success'          });        },        fail(err) => {          console.log('选择位置失败', err);          uni.showToast({            title'选择位置失败',            icon'none'          });        }      });    } catch (error) {      console.log('选择位置失败', error);      uni.showToast({        title'选择位置失败,请稍后重试',        icon'none'      });    }},// 引导用户开启权限guideUserToOpenPermission() {    uni.showModal({      title'权限提示',      content'需要获取您的地理位置信息才能使用此功能,是否前往设置页面开启权限?',      confirmText'去设置',      cancelText'取消',      success(res) => {        if (res.confirm) {          uni.openSetting({            success(res) => {              console.log('设置页面操作结果', res.authSetting);              if (res.authSetting['scope.userLocation']) {                uni.showToast({                  title'权限开启成功',                  icon'success'                });              }            }          });        }    }    });},// 处理定位错误handleLocationError(err) {    console.log('定位错误', err);    switch (err.errCode) {      case 1:      case 12:        // 用户拒绝授权        this.guideUserToOpenPermission();        break;      case 2:        // 位置信息不可用        uni.showToast({          title'无法获取位置信息,请检查定位服务是否开启',          icon'none'        });        break;      case 3:        // 定位超时        uni.showToast({          title'定位超时,请检查网络连接',          icon'none'        });        break;      case 13:        // 系统拒绝授权        uni.showToast({          title'系统拒绝授权,请检查系统定位权限设置',          icon'none'        });        break;      default:        // 其他错误        uni.showToast({          title'定位失败,请稍后重试',          icon'none'        });        break;    }}
常见错误code 
错误码
错误信息
原因
处理逻辑
1
permission denied
用户拒绝授权
引导用户去设置页面开启权限
2
position unavailable
位置信息不可用
提示用户检查定位服务是否开启
3
timeout
定位超时
增加超时时间,或提示用户检查网络
12
permission denied by user
用户拒绝授权
引导用户去设置页面开启权限
13
permission denied by system
系统拒绝授权
提示用户检查系统定位权限设置
注意事项
1. 必须用户主动触发:地理位置权限申请必须由用户主动点击按钮触发,不能自动弹出
2. 合理使用场景:只在必要的场景下请求地理位置权限,避免过度收集用户信息
3. 明确告知用户:在请求权限前,应该明确告知用户获取地理位置的用途
4. 保护用户隐私:获取到的地理位置信息必须妥善保管,不得滥用或泄露
5. 处理授权失败:当用户拒绝授权时,应该提供其他操作方式
6. 优化定位体验:在获取位置时,应该显示加载状态,避免用户误以为程序无响应
坐标类别
坐标系
描述
适用平台
wgs84
GPS坐标系
全球通用
gcj02
国测局坐标系
中国地区
bd09
百度坐标系
百度地图
常见问题 & 方案
问题1:定位不准
原因:
    • GPS信号弱
    • 网络定位误差
    • 坐标系转换问题
解决方案:
    • 开启GPS定位
    • 同时使用GPS、WiFi和基站定位
    • 确保坐标系正确
问题2:定位超时
原因:
    • GPS信号弱
    • 网络连接差
    • 设备性能问题
解决方案:
    • 增加超时时间
    • 优化定位参数
    • 提供定位失败的备选方案
问题3:iOS定位失败
原因:
    • iOS系统权限设置
    • 应用定位权限未开启
    • iOS系统版本限制
解决方案:
    • 引导用户在系统设置中开启定位权限
    • 确保应用在前台时请求定位
    • 适配不同iOS版本
问题4:Android定位失败
原因:
    • Android系统权限设置
    • 设备定位服务未开启
    • 不同Android厂商的定制化
解决方案:
    • 引导用户开启定位服务
    • 适配不同Android厂商的权限申请方式
    • 提供手动输入位置的备选方案