HarmonyOS NEXT实战:网络状态监控

##HarmonyOS Next实战##HarmonyOS SDK应用服务##教育##

参考资料: https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-network-61

@ohos.net.connection (网络连接管理) 网络连接管理提供管理网络一些基础能力,包括WiFi/蜂窝/Ethernet等多网络连接优先级管理、网络质量评估、订阅默认/指定网络连接状态变化、查询网络连接信息、DNS解析等功能。

connection.createNetConnection 创建一个NetConnection对象,netSpecifier指定关注的网络的各项特征;timeout是超时时间(单位是毫秒);netSpecifier是timeout的必要条件,两者都没有则表示关注默认网络。

思路:通过使用 @ohos.net.connection 的能力,在网络连接状态发生变化时,判断当前网络是否可以访问互联网,并将判断结果存储到 AppStorage 中。需要判断网络连接状态时,直接从 AppStorage 获取结果。

前提条件: 修改module.json5配置文件,增加网络权限:

    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO"
      }
    ]

增加NetworkUtil 工具类:

import { connection } from "@kit.NetworkKit";
import { BusinessError } from "@kit.BasicServicesKit";
import { promptAction } from "@kit.ArkUI";
import { hilog } from "@kit.PerformanceAnalysisKit";

export class NetworkUtil {
  private static netConnection: connection.NetConnection | undefined = undefined;
  public static JUDGE_NET_TAG: string = 'NetworkUtil.netConnection.isUseful';

  /**
   * 工具注册。
   * 作用:监控网络状态
   */
  static register() {
    if (NetworkUtil.netConnection === undefined) {
      NetworkUtil.init();
    }
  }

  /**
   * 获取网络连接状态
   * @returns boolean
   * true: 有网络
   * false: 无网络
   */
  static getStatus(): boolean {
    return NetworkUtil.judgeHasNet()
  }

  static continueWhenNetUsable(callback: () => void) {
    if (NetworkUtil.getStatus()) {
      callback()
    } else {
      promptAction.showToast({
        message: 'The network is not worked, please check your network',
        duration: 2000
      });
    }
  }

  private static init() {
    NetworkUtil.netConnection = connection.createNetConnection();
    NetworkUtil.netConnection.register(() => {
      Logger.info('connection register success');
    });

    NetworkUtil.netConnection.on('netAvailable', (data) => {
      Logger.info('NetworkUtil netAvailable ');
      AppStorage.setOrCreate(NetworkUtil.JUDGE_NET_TAG, NetworkUtil.judgeHasNet());
    });

    NetworkUtil.netConnection.on('netUnavailable', () => {
      Logger.info('NetworkUtil netUnavailable ');
      AppStorage.setOrCreate(NetworkUtil.JUDGE_NET_TAG, NetworkUtil.judgeHasNet());
    });

    NetworkUtil.netConnection.on('netCapabilitiesChange', (data: connection.NetCapabilityInfo) => {
      Logger.info('NetworkUtil netCapabilitiesChange');
      AppStorage.setOrCreate(NetworkUtil.JUDGE_NET_TAG, NetworkUtil.judgeHasNet());
    });

    // 订阅网络连接信息变化事件。调用register后,才能接收到此事件通知
    NetworkUtil.netConnection.on('netConnectionPropertiesChange', (data: connection.NetConnectionPropertyInfo) => {
      Logger.info('NetworkUtil netConnectionPropertiesChange');
      AppStorage.setOrCreate(NetworkUtil.JUDGE_NET_TAG, NetworkUtil.judgeHasNet());
    });

    NetworkUtil.netConnection.on('netLost', () => {
      Logger.info('NetworkUtil netLost');
      AppStorage.setOrCreate(NetworkUtil.JUDGE_NET_TAG, NetworkUtil.judgeHasNet());
    });
  }

  private static judgeHasNet(): boolean {
    try { // 获取当前网络连接
      let netHandle = connection.getDefaultNetSync();

      // 0-100 为系统预留的连接
      if (!netHandle || netHandle.netId < 100) {
        return false;
      }

      // 获取连接的属性
      let netCapability = connection.getNetCapabilitiesSync(netHandle);
      let cap = netCapability.networkCap;
      if (!cap) {
        return false;
      }

      for (let em of cap) {
        if (connection.NetCap.NET_CAPABILITY_VALIDATED === em) {
          return true;
        }
      }
    } catch (e) {
      let err = e as BusinessError;
      Logger.info('get netInfo error :' + JSON.stringify(err));
    }
    return false;
  }
}

class Logger{
  static info(...args: string[]){
    hilog.info(0x0000, '-logger-', getFormat(args), args);
  }
}

function getFormat(args: string[]) {
  let format = ''
  for (let i = 0; i < args.length; i++) {
    if (i == 0) {
      format = '%{public}s'
    } else {
      format += ', %{public}s'
    }
  }
  return format
}

页面NetworkUtilPage使用示例代码:

import { NetworkUtil } from '../../utils/NetworkUtil'
import { promptAction } from **********';

@Entry
@Component
struct NetworkUtilPage {
  //用法一:通过状态管理实时获取网络状态
  @StorageProp(NetworkUtil.JUDGE_NET_TAG)
  isNetConnectionUseful: boolean = true;

  aboutToAppear(): void {
    NetworkUtil.register()
  }

  build() {
    Column({ space: 10 }) {
      Text('NetworkUtil Page')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Text() {
        Span('watch network status is ')
        Span(JSON.stringify(this.isNetConnectionUseful))
          .fontColor(this.isNetConnectionUseful ? Color.Green : Color.Red)
          .fontWeight(600)
      }

      Button('getNetworkStatus').onClick(() => {
        //用法二:获取当前的网络状态
        const status = NetworkUtil.getStatus()
        promptAction.showToast({
          message: 'The network status is ' + JSON.stringify(status),
          duration: 5000
        });
      })

      Button('continue When Net Usable').onClick(() => {
        //用法三:有网络继续后续动作,无网则中断后续动作并且弹窗提示用户设置网络。
        NetworkUtil.continueWhenNetUsable(() => {
          //当网络中断,弹窗提示用户设置网络且不执行后续动作
          //当网络可用,继续执行
          promptAction.showToast({
            message: 'have net, continue!',
            duration: 5000
          });
        })
      })
    }
    .height('100%')
    .width('100%')
  }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-10 11:45
你不要过来啊啊啊啊啊啊啊
码农索隆:对面:“今天你不面也得面”
点赞 评论 收藏
分享
Lorn的意义:你这标个前端是想找全栈吗?而且项目确实没什么含金量,技术栈太少了,边沉淀边找吧 现在学院本想就业好一点四年至少得高三模式两年加油吧
点赞 评论 收藏
分享
05-29 09:02
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务