微信小程序获取用户地理位置失败的原因主要有3种情况:

1. 手机系统设置中地理位置未开启
2. 系统未给微信app授权
3. 用户未给小程序授权地理位置信息

所以需要继续完善下定位失败的处理逻辑。

1. 在获取地理位置信息失败后,首先判断用户手机系统定位服务是否开启 || 微信app是否有定位授权,两种情况任意一种不符合,显示地理位置获取失败状态;
2. 都符合的话调用uni.getLocation,success走成功的操作,fail表示未给小程序授权地理位置信息,显示地理位置获取失败状态;uni.openSetting打开设置,选择允许小程序授权。

涉及到一个关键点是,微信小程序判断手机有没有定位的方法
uni.getSystemInfo文档

//locationEnabled	地理位置的系统开关
//locationAuthorized	允许微信使用定位的开关
uni.getSystemInfo({
        success: (res) => {
          if (!res.locationEnabled || !res.locationAuthorized) {
            uni.showToast({
              title: '请确保手机系统定位已开启',
              icon: 'none',
              duration: 2000,
            })
        },
      })

获取地理位置失败显示效果图

android微博毁掉地址 微博地理位置获取失败_小程序

具体代码如下:

封装tool.js

//位置授权
export function getAuthorize () {
  return new Promise((resolve, reject) => {
    uni.authorize({
      scope: 'scope.userLocation',
      success: () => {
        // 1 用户允许授权
        // 2 用户之前已经同意授权,则不会出现弹窗,直接返回成功
        //  以上两种情况都会进入到success回调中
        resolve() // 允许授权
      },
      fail: () => {
        // 1 用户拒绝授权
        // 2 用户之前拒绝了授权,此接口会直接进入失败回调
        //  以上两种情况都会进入到fail回调中
        reject() // 拒绝授权
      },
    })
  })
}

父组件html

<template>
  <view>
    <!-- 未开启定位时状态 -->
    <notGps v-if="showNoGps" />
    <!-- 已开启定位时,正常显示页面 -->
    <view v-else class="index_root">
      <view>页面内容</view>
    </view>
  </view>
</template>

父组件js

<script>
import { getAuthorize } from '@/utils/tool.js' //引入位置授权
import notGps from './component/notGps.vue' // 引入未开启定位子组件
 data() {
   return {
    showNoGps: false,
   },
onLoad(e) {
    uni.showLoading({
      title: '加载中',
      mask: true,
    })
    //位置授权
    getAuthorize() 
    //用户允许小程序位置授权
      .then(() => {
        this.getSystemInfo()
       })
      //用户拒绝小程序位置授权
      .catch(() => {
        uni.hideLoading()
        this.getSystemInfo()
       })
 },
onShow() {
  if (this.showNoGps === true) {
    this.getSystemInfo()
  }
 }
  methods: {
    //获取手机系统信息
    getSystemInfo() {
      uni.getSystemInfo({
        success: (res) => {
          // 获取地理位置失败原因
          // 1.手机系统设置中地理位置未开启
          // 2.系统未给微信授权
          // 3.用户未给小程序授权地理位置信息
          if (!res.locationEnabled || !res.locationAuthorized) {
            uni.showToast({
              title: '请确保手机系统定位已开启',
              icon: 'none',
              duration: 2000,
            })
            this.showNoGps = true
          } else {
            this.getLocation()
          }
        },
    //先获取经纬度,然后再根据经纬度通过腾讯地图获取地址名称
    getLocation() {
      const that = this
      uni.getLocation({
        type: 'gcj02',
        success(res) {
        // 成功进行的操作
          let longitude = res.longitude
          let latitude = res.latitude
          getAddress(longitude, latitude)
            .then((res) => {
              let params = {
                city: res.result.address_component.city,
                name: res.result.address_reference.landmark_l2.title,
                lng: longitude,
                lat: latitude,
              }
              that.$store.commit('setLocation', params)
              // 获取定位成功,关闭获取地理位置失败显示效果
              that.showNoGps = false
              uni.showLoading({
                title: '加载中',
                mask: true,
              })
              //请求接口获取页面数据
              that.getGoodsList()
            })
            .catch((e) => {
              console.log(e, '解释地址失败')
            })
        },
        fail(err) {
        // 到这里进入fail就只有情况3,用户未给小程序授权地理位置信息,显示获取地理位置失败显示效果
          console.log(err, '获取经纬度失败')
          that.showNoGps = true
        },
      })
    },
      })
    },
   }
 </script>

notGps组件

<template>
  <view class="openGps">
    <image src="@/static/image/no_goods.png" class="empty-img"></image>
    <view class="empty-txt">
      为给您提供最佳服务,小程序需要获取您的当前位置以定位您附近的商户
    </view>
    <view class="handleBtn" @click="gotoLocation">点击开启定位</view>
  </view>
</template>

<script>
export default {
  data() {
    return {}
  },
  methods: {
  //打开小程序授权地理位置设置,不管用户操作是否授权,返回父组件页面之后,都会触发onShow周期函数里的代码
    gotoLocation() {
      uni.openSetting({
        success(res) {
          console.log(res.authSetting)
        },
      })
    },
  },
}
</script>

<style lang="scss">
.openGps {
  text-align: center;
  padding: 400rpx 80rpx 0 80rpx;
}
.empty-img {
  width: 380rpx;
  height: 284rpx;
}
.empty-txt {
  font-size: 28rpx;
  color: #999;
}
.handleBtn {
  background: linear-gradient(-10deg, #00ca20, #02bb34);
  font-size: 20rux;
  color: #fff;
  font-weight: bold;
  width: 300upx;
  text-align: center;
  height: 70upx;
  line-height: 70upx;
  border-radius: 35upx;
  margin: 30upx auto;
}
</style>