uni-app 网络权限和网络状态bug

发布于 1周前 作者 songsunli 来自 Uni-App

uni-app 网络权限和网络状态bug

项目信息 详情
产品分类 uniapp/App
PC开发环境 Windows
PC开发环境版本 win11家庭中文版22H2
HBuilderX类型 正式
HBuilderX版本 3.98
手机系统 iOS
手机系统版本 iOS 17
手机厂商 苹果
手机机型 13 pro
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

示例代码:

app.vue中代码

<script>  
    import Vue from 'vue';  
    export default {  
        data() {  
            return {  
                timerid: 0  
            }  
        },  
        onLaunch() {  
            // #ifdef APP-PLUS  
            this.network()  
            // #endif  

            // #ifdef H5  
            this.initFunc()  
            // #endif  

        },  
        onError() {  

            this.$control.msg('出现错误!');  
            // #ifdef APP-PLUS  
            uni.getNetworkType({  
                success: res => {  
                    if (res.networkType == 'none' || res.networkType == 'unknown') {  
                        this.$control.msg('网络错误');  
                        setTimeout(() => {  
                            plus.runtime.restart();  
                        }, 2000);  

                    }  
                }  
            });  
            // #endif  

        },  
        onShow() {  
            // 启动或重启即时通讯  
            this.$store.dispatch('chat/start');  
        },  
        onHide() {  
            // 断开即时通讯  
            this.$store.dispatch('chat/close');  
        },  
        methods: {  
            initFunc() {  
                // 检测客户端更新  
                this.$store.dispatch('update/update');  
                // 仅首次打开一次性加载数据  
                this.$store.dispatch('common/init');  
                // 同步购物车 本地 & 网络  
                this.$store.dispatch('cart/get');  
                // 同步 动态数据  
                this.$store.dispatch('statistics/get');  
                // uni.$emit('globalVarUpdated', this.hasNetworkPermission);  
            },  
            delTimer() {  
                if (this.timerid > 0) {  
                    clearInterval(this.timerid)  
                    this.timerid = 0;  
                }  
            },  
            network() {  
                console.log('检查权限开始')  
                var i = 0;  
                this.timerid = setInterval(() => {  
                    i++;  
                    console.log(1)  
                    // 判断网络类型  
                    uni.getNetworkType({  
                        success: res => {  
                            console.log(res.networkType + i)  
                            console.log(2)  
                            uni.showToast({  
                                title: "网络类型:" + res.networkType + i,  
                                icon: 'error'  
                            })  
                            if (res.networkType == 'none' || res.networkType == 'unknown') {  
                                if (i >= 5) {  
                                    uni.showToast({  
                                        title: "网络类型:" + res.networkType,  
                                        icon: 'error'  
                                    })  
                                    this.delTimer()  
                                }  
                            } else {  
                                if (res.networkType != 'wifi') {  
                                    this.$control.msg('当前使用非WIFI环境,请注意流量使用');  
                                }  
                                this.delTimer()  
                                this.initFunc()  
                            }  
                        }  
                    });  
                    console.log(3)  
                }, 2000)  
                console.log("获取权限结束" + this.timerid)  
            },  
        }  
    };  
</script>  

操作步骤:

安装app

启动同意使用网络权限

预期结果:

获得网络权限

首页渲染在获得网络权限之后

实际结果:

实际5G网络 getNetworkType 获取到的是unknown 导致逻辑没法处理

bug描述:

最初是该机安装后启动询问使用网络权限,同意后首页白屏,经过分析可能是页面先渲染后才拿到网络权限导致白屏的。后面做了获取网络状态再渲染,一些苹果机就正常了,目前发现了13 pro实际网络为5G 使用getNetworkType api获取到的网络类型是unknown 。


13 回复

这是调试 显示的getNetworkType 获取的网络状态



未授权网络权限的时候是获取不到网络类型的 uni.onNetworkStatusChange 可以通过这个api监听网络状态

你看第一张图,是获取了网络权限的

回复 7***@qq.com: 你getNetworkType 是在用户点击之后并且 有网络之后才调用的吗?

回复 DCloud_iOS_WZT: 是的,我可以确定是先同意使用网络,后通过定时器5次调用getNetworkType类型都是unknown,我有录屏,这里上传不了

回复 7***@qq.com: uni.onNetworkStatusChange 用这个api监听状态看下是啥

回复 DCloud_iOS_WZT: 看下图

回复 7***@qq.com: 感觉还是你代码getNetworkType 获取时机问题 首次请求未授权 要么你自己监听网络状态 要么给用户一个可以刷新页面的按钮

回复 7***@qq.com: 另外getNetworkType尽量不要在app.vue内部调用,尽量放到首页页面加载完成后

回复 DCloud_iOS_WZT: 别的手机都可以获取正确网络类型的,从原来在首页获取getNetworkType类型就有问题,后面为了调试才写的app.vue ,同意允许使用网络后,10多秒获取10多次都是unknown

回复 DCloud_iOS_WZT: 能不能处理一下这个bug啊,好难

客户现在没空配合,型号13 pro ,系统是ios17.1.2

在使用 uni-app 开发跨平台应用时,可能会遇到与网络权限和网络状态相关的 bug。以下是一些常见问题及其解决方案:


1. 网络权限问题

  • 问题描述:在 Android 平台上,应用无法访问网络,可能是因为缺少网络权限配置。
  • 解决方案
    1. manifest.json 文件中,确保已正确配置网络权限:
      {
        "app-plus": {
          "distribute": {
            "android": {
              "permissions": [
                "<uses-permission android:name=\"android.permission.INTERNET\"/>"
              ]
            }
          }
        }
      }
    2. 如果是 Android 10 及以上版本,还需要配置 ACCESS_NETWORK_STATE 权限:
      {
        "app-plus": {
          "distribute": {
            "android": {
              "permissions": [
                "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>"
              ]
            }
          }
        }
      }

2. 网络状态检测问题

  • 问题描述:使用 uni.getNetworkTypeuni.onNetworkStatusChange 时,无法正确获取网络状态。
  • 解决方案
    1. 确保在 manifest.json 中配置了 ACCESS_NETWORK_STATE 权限(如上所述)。
    2. 检查代码逻辑,确保正确使用 API:
      uni.getNetworkType({
        success(res) {
          console.log('网络类型:', res.networkType);
        },
        fail(err) {
          console.error('获取网络类型失败:', err);
        }
      });
      
      uni.onNetworkStatusChange((res) => {
        console.log('网络状态变化:', res.isConnected, res.networkType);
      });
    3. 在 Android 平台上,部分设备可能需要动态申请权限。可以使用 uni.authorize 动态申请权限:
      uni.authorize({
        scope: 'scope.networkType',
        success() {
          console.log('网络权限已授权');
        },
        fail() {
          console.error('网络权限未授权');
        }
      });

3. iOS 平台网络状态问题

  • 问题描述:在 iOS 平台上,uni.getNetworkTypeuni.onNetworkStatusChange 返回的结果不准确。
  • 解决方案
    1. 确保在 manifest.json 中配置了 NSLocalNetworkUsageDescription 权限:
      {
        "app-plus": {
          "distribute": {
            "ios": {
              "infoPlist": {
                "NSLocalNetworkUsageDescription": "需要访问网络以检测网络状态"
              }
            }
          }
        }
      }
    2. 在 iOS 平台上,网络状态检测可能受系统限制,建议结合后端接口进行网络状态验证。

4. H5 平台网络状态问题

  • 问题描述:在 H5 平台上,uni.getNetworkTypeuni.onNetworkStatusChange 无法使用。
  • 解决方案
    1. H5 平台不支持原生网络状态检测,可以使用浏览器的 navigator.onLine API 进行检测:
      const isOnline = navigator.onLine;
      console.log('网络状态:', isOnline ? '在线' : '离线');
      
      window.addEventListener('online', () => {
        console.log('网络已连接');
      });
      
      window.addEventListener('offline', () => {
        console.log('网络已断开');
      });

5. 其他常见问题

  • 问题描述:网络请求失败,但无法确定是网络权限问题还是代码问题。
  • 解决方案
    1. 使用 uni.request 发起请求时,检查返回的错误信息:
      uni.request({
        url: 'https://example.com/api',
        success(res) {
          console.log('请求成功:', res.data);
        },
        fail(err) {
          console.error('请求失败:', err);
        }
      });
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!