网络状态变化订阅 

  • 常见事件订阅场景,触发此类型事件:

      • netAvailable: 网络可用事件
      • netCapabilitiesChange: 网络能力变化事件
      • netConnectionPropertiesChange: 网络连接信息变化事件
      • netLost: 网络丢失事件
      • netLost: 网络丢失事件,丢失Wi-Fi网络
      • netAvailable: 网络可用事件,蜂窝网络可用
      • netCapabilitiesChange: 网络能力变化事件

网络连接管理查看

将接收指定网格的状态变化封装为工具类

1. 需申请网络权限

ohos.permission.GET_NETWORK_INFO 允许应用获取数据网络信息

建议同时在申请个 ohos.permission.INTERNET 允许使用Internet网络权限

 申请权限以下信息表示:

        "name":权限名称
        "reason":申请理由
        "usedScene":权限使用场景
        "abilities":可调用该权限的模块

注:申请user_grant类权限时建议填写上述信息

         "when":权限使用时机(不可为空)

               inuse(使用时)

               always(始终)

2.封装为工具类方便后续复用  

因为网络状态(蓝牙,Wi-Fi)这种工具类为常用工具


const TAG: string = 'ConnectionUtils

设置一个打印时的标识,通过hilog打印信息的时候快速找到对应信息 

hilog.info( )

        info(domain: number, tag: string, format: string, ...args: any[]) : void       

        第一个参数domain:

        日志对应的领域标识,通过领域标识可找到对应的这个组内的信息

        第二个参数tag:

        指定日志标识,可以为任意字符串,列入上面那个就是咱单独设置的标识,方便快速找到

        第三个参数format:

        具体的信息,打印你想要的消息  %{public}s 接收后面的参数第一个类型为s的实参

        因为部分信息可能不方便透露,可设置private私有

        %{}s 这种是接收后面的参数的要对应上

        例子:hilog.info(0x0001, "testTag", "%{public}s World %{private}d", "hello", 3);

        隐私标识分为{public}和{private},缺省为{private}。标识{public}的内容明文输出

        标识{private}的内容以<private>过滤回显

3.定义好类名后,创建一个NetConnection对象

netConnection = connection.createNetConnection( )

通过该网络连接管理对象,操控里面的实例方法(网络连接的句柄)

创建一个NetConnection对象,调用该(网络连接管理)对象的实例方法,其中:

netSpecifier指定关注的网络的各项特征;

timeout是超时时间(单位是毫秒);

netSpecifier是timeout的必要条件,两者都没有则表示关注默认网络

createNetConnection(netSpecifier?: NetSpecifier, timeout?: number): NetConnection

4. 调用实例化对象register方法开启监听网络状态变化

下面的方法均是:NetConnection  网络连接的句柄

register(callback: AsyncCallback<void>): void 订阅指定网络状态变化的通知

参数详解: 

callback回调函数:当订阅指定网络状态变化的通知成功,error为undefined,否则为错误对象

当执行出错时,会打印出错信息;执行没问题就没有报错信息,执行正确没信息打印,例如:

调用该类的前提一定是要先启动监听

注意: 使用完register接口后需要及时调用unregister取消注册

Tips:在程序创建时就可以注册监听器了

5. 监听具体的类型(Wi-Fi,蓝牙等)

该自定义方法一般用在组件内,例如:在登陆时判断网络情况,给用户网络反馈

connection.getDefaultNet( ): Promise<NetHandle>

参数详解: 

获取默认激活的数据网络,使用Promise方式作为异步方法

可以使用getNetCapabilities去获取网络的类型、拥有的能力等信息

注意:需要权限:ohos.permission.GET_NETWORK_INFO,否则可能运行不了

调用该方法会返回一个connection.NetHandle对象,此对象会有个我们需要的属性:

netId:网络ID,取值为0代表没有默认网络,其余取值必须大于等于100

所以当取值为为0时代表没有网络,可打印一些信息给用户提醒

当上述网络ID正常时,可以使用getNetCapabilities去获取网络的类型、拥有的能力等信息

getNetCapabilities(netHandle: NetHandle): Promise<NetCapabilities>

获取netHandle对应的网络的能力信息,使用Promise方式作为异步方法

参数详解: 

netHandle: 数据网络的句柄(getDefaultNet运行完得到的是该类型的参数)

故上述运行完后在.then里面接收上述参数,继续调用

上述方法运行结束后,获取一个connection.NetCapabilities的结果

其中我们需要的是.then得到的形参参数名.bearerTypes,该参数会获得你当前网络的类型下标
例如:data.bearerTypes,参数说明:

bearerTypes:网络类型 数组里面只包含了一种具体的网络类型,参数为:

NetBearType:网络类型(通过获得的类型进行if匹配),具体为:

BEARER_CELLULAR 0

蜂窝网络

BEARER_WIFI 1

Wi-Fi网络

BEARER_BLUETOOTH12+ 2

蓝牙网络

BEARER_ETHERNET 3

以太网网络

BEARER_VPN12+ 4 VPN网络。

获取的结果可能是多个类型,将得到的结果存储到set中:

        set 是一个集合,先进先出,不会插入重复数据,数据支持类型的多样性

       

将得到的结果集存到数组中,遍历该数组获取,通过if下标匹配具体什么类型网络:

全部可参考下面代码:

result是因为我自身组件调用时有个判断需要需要布尔类型(返回的结果可凭需要自己定义)

6. 订阅网络可用事件(当网络变化时触发的事件)

注意:此接口调用之前需要先调用register接口

通过上述3获取的实例NetConnection对象,调用该对象里的on方法:

on(type: '具体事件', callback: Callback<NetHandle>): void

具体参数:

        type:订阅事 函数执行此事件 调用该事件callback(回调函数)

        callback:回调函数,返回数据网络句柄

例子:netAvailable:数据网络可用事件

当数据网络可用时自行触发该事件

Tips:当对多种触发事件进行考虑时,可将所有事件封装为一个方法

编译器执行该方法时,会根据现有情况,执行相对应的事件

Tips:当页面搭建好时,监听页面网络事件变化:

7. 关闭监听(不销毁占内存等)

unregister(callback: AsyncCallback<void>): void 取消订阅默认网络状态变化通知

可在业务逻辑处理结束时取消订阅,但不应该放在事件回调函数中调用(组件销毁时取消)

callback回调函数:当取消订阅指定网络状态变化的通知成功,error为undefined,否则为错误对象

Tips:当程序快销毁时,注销监听器,结束该监听器

取消订阅默认网络状态变化的通知。可在业务逻辑处理结束时取消订阅,但不应该放在事件回调函数中调用

封装好的网络连接状态模版:

import { connection } from "@kit.NetworkKit"
import { BusinessError } from "@kit.BasicServicesKit"
import { loggerUtils } from "../info/LoggerUtils"
import { promptAction } from "@kit.ArkUI"
import { fileIo as fs } from '@kit.CoreFileKit';


export class ConnectionUtils {
  // 创建一个网络链接管理的对象
  netConnection: connection.NetConnection

  constructor() {
    this.netConnection = connection.createNetConnection()
  }

  openRegister() {

    this.netConnection.register((error: BusinessError) => {
      if (error) {
        loggerUtils.warn('订阅网络变化通知出错,错误为:', JSON.stringify(error))
        return
      }
      loggerUtils.info('成功开启', '网络变化通知')
    })
  }

  getNetInfo() {
    // 获取默认激活的数据网络
    connection.getDefaultNet().then((NetHandle) => {
      if (NetHandle.netId == 0) {
        loggerUtils.info('当前网络', '没有默认网络')
        return
      }
      loggerUtils.info("Succeeded to get data: ", JSON.stringify(NetHandle))
      // 获取netHandle对应的网络的能力信息
      connection.getNetCapabilities(NetHandle, (err, data) => {
        if (err) {
          loggerUtils.info('Failed to get net capabilities', JSON.stringify(err))
          return
        }
        loggerUtils.info('Succeeded to get data', JSON.stringify(data)) // 打印拿到的网络信息
        // 网络类型 只包含了一种具体的网络类型
        for (let i of data.bearerTypes) {
          if (i == 0) {
            promptAction.showToast({
              message: '蜂窝网络',
              duration: 5000
            })
            loggerUtils.info('网络类型', 'BEARER_CELLULAR')
          } else if (i == 1) {
            promptAction.showToast({
              message: 'Wi-Fi网络',
              duration: 5000
            })
            loggerUtils.info('网络类型', 'BEARER_WIFI')
          } else if (i == 2) {
            promptAction.showToast({
              message: '蓝牙网络',
              duration: 5000
            })
            loggerUtils.info('网络类型', 'BEARER_BLUETOOTH')
          } else if (i == 3) {
            promptAction.showToast({
              message: '以太网网络',
              duration: 5000
            })
            loggerUtils.info('网络类型', 'BEARER_ETHERNET')
          } else {
            promptAction.showToast({
              message: 'VPN网络',
              duration: 5000
            })
            loggerUtils.info('网络类型', 'BEARER_VPN')
          }
        }
      })
    })
  }

  onIncident() {
    this.netConnection.on('netAvailable', (data) => {
      promptAction.showToast({
        message: '数据网络可用事件',
        duration: 5000
      })
    });

    this.netConnection.on('netLost', (data) => {
      promptAction.showToast({
        message: '网络严重中断或正常断开事件',
        duration: 5000
      })
    });

    this.netConnection.on('netConnectionPropertiesChange', (data) => {
      promptAction.showToast({
        message: '网络连接信息变化事件',
        duration: 5000
      })
    });

    this.netConnection.on('netCapabilitiesChange', (data) => {
      promptAction.showToast({
        message: '网络能力变化事件',
        duration: 5000
      })
    });
  }

  closeRegister() {
    this.netConnection.unregister((error: BusinessError) => {
      if (error) {
        loggerUtils.warn('关闭网络变化通知出错,错误为:', JSON.stringify(error))
        return
      }
      loggerUtils.info('成功关闭', '网络变化通知')
    })
  }
}

export let connectionUtils = new ConnectionUtils()

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐