HarmonyOS中连接Wifi相关示例

69 阅读3分钟

1、连接WIfi管理类封装

/**
 * wifi管理类
 */
export class WifiManager {

  /**
   * 获取WiFi的Ip信息
   * @param isToString 是否转换为字符串
   * @returns
   */
  static getIpInfo(isToString: boolean = true): wifiManager.IpInfo {
    let ipInfo: wifiManager.IpInfo = wifiManager.getIpInfo()

    // 使用lodash 的 map 方法将每个字段转换为字符串
    Object.keys(ipInfo).forEach(key => {
      if (key !== 'leaseDuration' && isToString) ipInfo[key] = WifiManager.getIpAddrFromNum(ipInfo[key])
    })
    return ipInfo

  }

  /**
   * 计算子网掩码
   * @param prefixLength
   * @returns
   */
  calculateSubnetMask(prefixLength: number): string {
    // 计算每个字节的子网掩码部分
    let subnetMask = '';
    for (let i = 0; i < 4; i++) {
      // 每个字节中的有效位数
      const bits = Math.min(prefixLength, 8);
      // 计算子网掩码字节的值并添加到结果字符串
      subnetMask += (256 - Math.pow(2, 8 - bits)) + '.';
      // 更新剩余的位数
      prefixLength -= bits;
    }
    // 去除末尾的点并返回子网掩码字符串
    return subnetMask.slice(0, -1);
  }

  /**
   * 计算广播地址
   * @param ipAddress
   * @param subnetMask
   * @returns
   */
  calculateBroadcastAddress(ipAddress: string, subnetMask: string): string {
    // 将IP地址字符串转换为数字数组
    const ipParts: number[] = ipAddress.split('.')
      .map(Number);
    // 将子网掩码字符串转换为数字数组
    const subnetParts: number[] = subnetMask.split('.')
      .map(Number);
    // 计算每个字节的广播地址部分
    const broadcastParts: number[] = [];
    for (let i = 0; i < 4; i++) {
      // 计算每个字节的广播地址值并添加到结果数组
      broadcastParts.push(ipParts[i] | (255 - subnetParts[i]));
    }
    // 将结果数组转换为字符串并使用点分隔
    return broadcastParts.join('.');
  }

  /**
   * 获取路由广播地址
   * @returns
   */
  getRouteBroadcastIp(): string {
    const defaultNet = connection.getDefaultNetSync();
    // 获取默认网络的链路信息
    const connectionProperties = connection.getConnectionPropertiesSync(defaultNet);
    // 提取链路信息
    const linkAddress = connectionProperties.linkAddresses[0];
    let broadcastAddress: string = "";
    if (linkAddress) {
      // 获取 IP 地址
      // this.IPAddress = linkAddress.address.address
      let ip = linkAddress.address.address;
      // 计算子网掩码(了解)
      let subnetMask = this.calculateSubnetMask(linkAddress.prefixLength)
      // 计算广播地址(了解)
      broadcastAddress = this.calculateBroadcastAddress(ip, subnetMask)
    }
    return broadcastAddress
  }

  /**
   * 发送广播
   * @param params
   * @param broadcast 是否广播
   * @param getData 接收数据回调
   */
  // send(params: number[], ip: string, broadcast: boolean, getData: (data: Record<string, string>) => void) {
  send(params: number[], broadcast: boolean, getData?: (data: Record<string, string>) => void) {
    // let params = [0x66, 0x39, 0x01, 0x01]
    let buf = buffer.from(params)
    let dataArr = buf.buffer

    let udp: socket.UDPSocket = socket.constructUDPSocketInstance()
    let bindAddr: socket.NetAddress = {
      address: '0.0.0.0',
      port: 58090
    }
    udp.bind(bindAddr, (err: BusinessError) => {
      if (err) {
        console.log('bind fail')
        return;
      }
      console.log('bind success')
    })

    udp.setExtraOptions({
      broadcast: broadcast
    }).then(() => {
      udp.on('message', (value: socket.SocketMessageInfo) => {
        let data: string = ""
        for (let i: number = 0; i < value.message.byteLength; i++) {
          let uint8Array = new Uint8Array(value.message)
          let messages = uint8Array[i]
          let message = String.fromCharCode(messages)
          data += message
        }
        getData && getData({'data': data, 'remoteInfo': JSON.stringify(value.remoteInfo)} as Record<string, string>)
      })
      udp.send({
        data: dataArr,
        address: {
          // address: ip,
          address: this.getRouteBroadcastIp(),
          port: 58090
        }
      })
    })
  }

  /**
   * 根据数字形式的IP地址获取字符串形式的IP地址
   * @param ipNum
   * @returns
   */
  static getIpAddrFromNum(ipNum: number): string {
    // console.log('wifi信息', (ipNum >>> 24) + '.' + (ipNum >> 16 & 0xFF) + '.' + (ipNum >> 8 & 0xFF) + '.' + (ipNum & 0xFF))
    return (ipNum >>> 24) + '.' + (ipNum >> 16 & 0xFF) + '.' + (ipNum >> 8 & 0xFF) + '.' + (ipNum & 0xFF);
  }

}

2、调用测页面


import wifiManager from '@ohos.wifiManager';
import { promptAction } from '@kit.ArkUI';
import { LoggerManager, WifiManager } from '@xfh/helper';

@Entry
@Component
struct WifiPage {
  build() {
    Navigation() {
      Scroll() {
        Column({ space: 10 }) {
          Text('WiFi信息')
          Button('WiFi是否打开')
            .onClick(() => {
              try {
                let isWifiActive = wifiManager.isWifiActive()
                if (isWifiActive) {
                  promptAction.showToast({ message: 'WiFi已打开' })
                } else {
                  promptAction.showToast({ message: 'WiFi已关闭' })
                }
              } catch (error) {
                console.error("failed:" + JSON.stringify(error))
                promptAction.showToast({ message: '检查WiFi失败' })
              }
            })

          Button('检查是否连接WiFi')
            .onClick(() => {
              try {
                let ret = wifiManager.isConnected()
                if (ret) {
                  promptAction.showToast({ message: '已连接WiFi' })
                } else {
                  promptAction.showToast({ message: '未连接WiFi' })
                }
              } catch (error) {
                console.error("failed:" + JSON.stringify(error));
              }
            })

          Button('当前连接WiFi是否是手机热点')
            .onClick(() => {
              try {
                let isMeteredHotspot = wifiManager.isMeteredHotspot();
                promptAction.showToast({ message: '当前连接WiFi是否是手机热点:' + isMeteredHotspot })
              } catch (error) {
                LoggerManager.error("failed:" + JSON.stringify(error));
              }
            })

          Button('获取WiFi连接信息')
            .onClick(() => {
              wifiManager.getLinkedInfo((err, data) => {
                if (err) {
                  LoggerManager.error("get linked info error")
                  return
                }
                if (data.ssid) {
                  AlertDialog.show({ message: JSON.stringify(data, null, 2) })
                } else {
                  promptAction.showToast({ message: '未连接WiFi' })
                  LoggerManager.print(data)
                }
              })
            })

          Button('获取WiFi的Ip信息(string)')
            .onClick(() => {
              let ipInfo = WifiManager.getIpInfo()
              AlertDialog.show({ message: JSON.stringify(ipInfo, null, 2) })
            })

          Button('获取WiFi的Ip信息(number)')
            .onClick(() => {
              let ipInfo = WifiManager.getIpInfo(false)
              AlertDialog.show({ message: JSON.stringify(ipInfo, null, 2) })
            })

        }
        .constraintSize({ minHeight: '100%' })
      }
      .width('100%')
      .height('100%')
    }
    .title('WiFi管理测试')
    .titleMode(NavigationTitleMode.Mini)
  }
}

3、效果图

mmexport1756887245590.jpg