一、文档概述

1.1 适用范围

  • 适用系统:OpenHarmony 4.0 / 5.0 / 6.0(仅支持 Full SDK,Public SDK 不具备 WiFi 完整能力)

  • 开发语言:ArkTS

  • 适用设备:IoT 开发板、平板、具备 WiFi 模块的 OpenHarmony 设备

1.2 核心功能

  • WiFi 开关控制(开启/关闭)

  • WiFi 扫描(获取周边可用 WiFi 列表)

  • WiFi 连接(支持加密/非加密网络,适配 WPA2/PSK 常用加密类型)

  • WiFi 断开连接

  • 获取当前 WiFi 连接信息(SSID、信号强度等)

  • WiFi 状态监听(实时监听开关、连接状态变化)

二、前置配置

2.1 SDK 环境要求

必须使用OpenHarmony Full SDK,Public SDK 不支持 WiFiManager 相关 API,需在 DevEco Studio 中配置对应版本的 Full SDK(配置路径:File → Project Structure → SDK → OpenHarmony SDK)。

2.2 权限配置(必配)

在项目 module.json5 文件中添加 WiFi 相关权限,否则会导致 API 调用失败、功能异常。

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "用于WiFi网络通信",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.GET_WIFI_INFO",
        "reason": "用于获取WiFi连接信息",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.SET_WIFI_INFO",
        "reason": "用于配置WiFi连接参数",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "用于扫描周边WiFi(需位置权限支持)",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.ACCESS_WIFI_STATE",
        "reason": "用于获取WiFi开关状态",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      },
      {
        "name": "ohos.permission.CHANGE_WIFI_STATE",
        "reason": "用于控制WiFi开关",
        "usedScene": {
          "abilities": ["*"],
          "when": "always"
        }
      }
    ]
  }
}

2.3 动态权限申请

应用需要使用 ststem_core  签名。

三、核心代码实现(参考指定目录)

3.1 完整工具类代码(WifiUtil.ts)

import wifiManager from '@ohos.wifiManager';
import { WifiSecurityType } from '@ohos.wifiManager';
import { BusinessError } from '@ohos.base';
import { Logger } from '../log/Logger'; // 替换为项目自身的日志工具路径

const TAG = "WifiUtil"; // 日志标签

/**
 * OpenHarmony Full SDK WiFi 工具类
 * 封装WiFi开关、扫描、连接、断开、状态监听等核心功能
 */
export class WifiUtil {

  /**
   * 检查WiFi是否已开启
   * @returns boolean 开启返回true,关闭返回false
   */
  static isWifiEnabled(): boolean {
    try {
      const isEnabled = wifiManager.isWifiActive();
      Logger.info(TAG, `检查WiFi状态:${isEnabled ? '已开启' : '未开启'}`);
      return isEnabled;
    } catch (e) {
      Logger.error(TAG, `检查WiFi状态失败:${(e as BusinessError).message}`);
      return false;
    }
  }

  /**
   * 开启WiFi
   */
  static enableWifi() {
    try {
      if (!this.isWifiEnabled()) {
        wifiManager.enableWifi();
        Logger.info(TAG, "WiFi开启成功");
      } else {
        Logger.info(TAG, "WiFi已处于开启状态,无需重复操作");
      }
    } catch (e) {
      Logger.error(TAG, `WiFi开启失败:${(e as BusinessError).message}`);
    }
  }

  /**
   * 关闭WiFi
   */
  static disableWifi() {
    try {
      if (this.isWifiEnabled()) {
        wifiManager.disableWifi();
        Logger.info(TAG, "WiFi关闭成功");
      } else {
        Logger.info(TAG, "WiFi已处于关闭状态,无需重复操作");
      }
    } catch (e) {
      Logger.error(TAG, `WiFi关闭失败:${(e as BusinessError).message}`);
    }
  }

  /**
   * 扫描周边WiFi,返回扫描结果列表
   * @returns Promise<wifiManager.WifiScanInfo[]> WiFi扫描列表
   */
  static async scanWifi(): Promise<wifiManager.WifiScanInfo[]> {
    return new Promise((resolve, reject) => {
      try {
        // 1. 先检查WiFi是否开启,未开启则先开启
        if (!this.isWifiEnabled()) {
          this.enableWifi();
          // 延迟500ms,确保WiFi开启后再扫描(避免扫描失败)
          setTimeout(() => {
            this.doScan(resolve, reject);
          }, 500);
        } else {
          this.doScan(resolve, reject);
        }
      } catch (e) {
        Logger.error(TAG, `WiFi扫描异常:${(e as BusinessError).message}`);
        reject(e);
      }
    });
  }

  /**
   * 扫描WiFi核心逻辑(内部方法,不对外暴露)
   */
  private static doScan(resolve: (value: wifiManager.WifiScanInfo[]) => void, reject: (reason?: any) => void) {
    try {
      // 启动WiFi扫描
      const scanResult = wifiManager.startScan();
      if (!scanResult) {
        Logger.error(TAG, "WiFi扫描启动失败");
        reject(new Error("扫描启动失败"));
        return;
      }
      // 获取扫描结果列表
      const scanList = wifiManager.getScanInfoList();
      Logger.info(TAG, `WiFi扫描完成,共发现${scanList.length}个WiFi`);
      resolve(scanList);
    } catch (e) {
      Logger.error(TAG, `WiFi扫描失败:${(e as BusinessError).message}`);
      reject(e);
    }
  }

  /**
   * 连接加密WiFi(WPA2/PSK,最常用加密类型)
   * @param ssid WiFi名称(不可为空)
   * @param pwd WiFi密码(不可为空,长度需符合WiFi密码规范)
   */
  static connectWifi(ssid: string, pwd: string) {
    if (!ssid || !pwd) {
      Logger.error(TAG, "WiFi名称或密码不能为空");
      return;
    }

    try {
      // 配置WiFi连接参数
      const wifiConfig: wifiManager.WifiDeviceConfig = {
        ssid: ssid,
        preSharedKey: pwd,
        securityType: WifiSecurityType.WIFI_SEC_TYPE_PSK, // 加密类型:WPA2/PSK
        bssid: "", // 可选,不指定则自动匹配对应SSID的BSSID
        frequency: 0 // 可选,自动匹配频率
      };

      // 添加WiFi配置,返回配置ID(-1表示添加失败)
      const networkId = wifiManager.addDeviceConfig(wifiConfig);
      if (networkId === -1) {
        Logger.error(TAG, `WiFi配置添加失败,SSID:${ssid}`);
        return;
      }

      // 根据配置ID连接WiFi
      const connectResult = wifiManager.connectToNetwork(networkId);
      if (connectResult) {
        Logger.info(TAG, `WiFi连接成功,SSID:${ssid}`);
      } else {
        Logger.error(TAG, `WiFi连接失败,SSID:${ssid}`);
        // 连接失败时,删除无效配置
        wifiManager.removeDeviceConfig(networkId);
      }
    } catch (e) {
      Logger.error(TAG, `WiFi连接异常,SSID:${ssid},错误信息:${(e as BusinessError).message}`);
    }
  }

  /**
   * 连接无密码WiFi
   * @param ssid WiFi名称(不可为空)
   */
  static connectWifiNoPwd(ssid: string) {
    if (!ssid) {
      Logger.error(TAG, "WiFi名称不能为空");
      return;
    }

    try {
      const wifiConfig: wifiManager.WifiDeviceConfig = {
        ssid: ssid,
        securityType: WifiSecurityType.WIFI_SEC_TYPE_OPEN, // 无加密类型
        bssid: "",
        frequency: 0
      };

      const networkId = wifiManager.addDeviceConfig(wifiConfig);
      if (networkId === -1) {
        Logger.error(TAG, `无密码WiFi配置添加失败,SSID:${ssid}`);
        return;
      }

      const connectResult = wifiManager.connectToNetwork(networkId);
      if (connectResult) {
        Logger.info(TAG, `无密码WiFi连接成功,SSID:${ssid}`);
      } else {
        Logger.error(TAG, `无密码WiFi连接失败,SSID:${ssid}`);
        wifiManager.removeDeviceConfig(networkId);
      }
    } catch (e) {
      Logger.error(TAG, `无密码WiFi连接异常,SSID:${ssid},错误信息:${(e as BusinessError).message}`);
    }
  }

  /**
   * 断开当前WiFi连接
   */
  static disconnectWifi() {
    try {
      if (this.isWifiEnabled() && this.getCurrentWifiInfo().ssid) {
        wifiManager.disconnect();
        Logger.info(TAG, "WiFi断开连接成功");
      } else {
        Logger.info(TAG, "当前未连接WiFi,无需断开");
      }
    } catch (e) {
      Logger.error(TAG, `WiFi断开失败:${(e as BusinessError).message}`);
    }
  }

  /**
   * 获取当前连接的WiFi信息
   * @returns wifiManager.WifiLinkedInfo 当前WiFi连接信息(未连接时部分字段为空)
   */
  static getCurrentWifiInfo(): wifiManager.WifiLinkedInfo {
    try {
      const linkedInfo = wifiManager.getLinkedInfo();
      Logger.info(TAG, `当前WiFi信息:SSID=${linkedInfo.ssid},信号强度=${linkedInfo.rssi}`);
      return linkedInfo;
    } catch (e) {
      Logger.error(TAG, `获取当前WiFi信息失败:${(e as BusinessError).message}`);
      return {} as wifiManager.WifiLinkedInfo;
    }
  }

  /**
   * 监听WiFi状态变化(开关状态、连接状态)
   * @param callback 状态变化回调函数,参数为状态码
   */
  static listenWifiState(callback: (state: number) => void) {
    try {
      wifiManager.on('wifiStateChange', (state: number) => {
        Logger.info(TAG, `WiFi状态变化,状态码:${state}`);
        callback(state);
      });
    } catch (e) {
      Logger.error(TAG, `监听WiFi状态失败:${(e as BusinessError).message}`);
    }
  }

  /**
   * 取消监听WiFi状态变化
   */
  static unlistenWifiState() {
    try {
      wifiManager.off('wifiStateChange');
      Logger.info(TAG, "取消WiFi状态监听成功");
    } catch (e) {
      Logger.error(TAG, `取消WiFi状态监听失败:${(e as BusinessError).message}`);
    }
  }
}

四、页面调用示例

以下是 ArkTS 页面调用 WifiUtil 工具类的示例,实现 WiFi 开关、扫描、连接等功能,可直接复制到项目页面中使用。

import { WifiUtil } from '../com/ohos/iot/wifi/WifiUtil';
import { requestWifiPermissions } from '../utils/permissionUtil'; // 引用动态权限申请方法
import { UIAbilityContext } from '@ohos.app.ability.UIAbilityContext';

@Entry
@Component
struct WifiConnectPage {
  // 页面上下文(用于动态申请权限)
  private context: UIAbilityContext = getContext(this) as UIAbilityContext;
  // 扫描到的WiFi列表
  private wifiList: wifiManager.WifiScanInfo[] = [];

  build() {
    Column() {
      // 页面标题
      Text("WiFi连接功能演示")
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 30 });

      // 1. 动态申请权限
      Button("申请WiFi相关权限")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          requestWifiPermissions(this.context);
        });

      // 2. 开启WiFi
      Button("开启WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          WifiUtil.enableWifi();
        });

      // 3. 关闭WiFi
      Button("关闭WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          WifiUtil.disableWifi();
        });

      // 4. 扫描WiFi
      Button("扫描周边WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(async () => {
          this.wifiList = await WifiUtil.scanWifi();
          console.log("扫描到的WiFi列表:", JSON.stringify(this.wifiList));
        });

      // 5. 连接加密WiFi(替换为实际的WiFi名称和密码)
      Button("连接加密WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          WifiUtil.connectWifi("你的WiFi名称", "你的WiFi密码");
        });

      // 6. 连接无密码WiFi(替换为实际的WiFi名称)
      Button("连接无密码WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          WifiUtil.connectWifiNoPwd("无密码WiFi名称");
        });

      // 7. 断开WiFi
      Button("断开当前WiFi")
        .width('80%')
        .height(40)
        .margin({ bottom: 15 })
        .onClick(() => {
          WifiUtil.disconnectWifi();
        });

      // 8. 获取当前WiFi信息
      Button("查看当前WiFi信息")
        .width('80%')
        .height(40)
        .onClick(() => {
          const wifiInfo = WifiUtil.getCurrentWifiInfo();
          console.log(`当前连接SSID:${wifiInfo.ssid},信号强度:${wifiInfo.rssi}`);
        });
    }
    .padding(20)
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Top)
    // 页面加载时监听WiFi状态
    .onPageShow(() => {
      WifiUtil.listenWifiState((state) => {
        // 处理WiFi状态变化(根据状态码做对应逻辑)
        switch (state) {
          case 0:
            console.log("WiFi状态:未开启");
            break;
          case 1:
            console.log("WiFi状态:开启中");
            break;
          case 2:
            console.log("WiFi状态:已开启");
            break;
          case 3:
            console.log("WiFi状态:关闭中");
            break;
        }
      });
    })
    // 页面销毁时取消监听
    .onPageHide(() => {
      WifiUtil.unlistenWifiState();
    });
  }
}

五、关键说明

5.1 WiFi 状态码说明

wifiStateChange 回调中的状态码对应含义如下,可用于页面状态展示:

状态码 状态描述
0 WiFi 未开启
1 WiFi 开启中
2 WiFi 已开启
3 WiFi 关闭中

5.2 核心 API 说明

以下是工具类中用到的核心 OpenHarmony WiFi API,对应官方文档:

  • wifiManager.isWifiActive():判断WiFi是否开启

  • wifiManager.enableWifi():开启WiFi

  • wifiManager.disableWifi():关闭WiFi

  • wifiManager.startScan():启动WiFi扫描

  • wifiManager.getScanInfoList():获取扫描结果列表

  • wifiManager.addDeviceConfig():添加WiFi连接配置

  • wifiManager.connectToNetwork():根据配置ID连接WiFi

  • wifiManager.disconnect():断开当前WiFi连接

  • wifiManager.getLinkedInfo():获取当前连接信息

  • wifiManager.on('wifiStateChange'):监听WiFi状态变化

六、常见问题排查

6.1 扫描不到WiFi

  • 未开启位置权限:动态申请 LOCATION 权限,且确保用户允许

  • WiFi未开启:扫描前先调用 enableWifi() 开启WiFi

  • 扫描时机过早:WiFi开启后需延迟500ms左右再扫描(工具类已处理)

  • 设备WiFi模块异常:检查开发板WiFi硬件是否正常

6.2 WiFi连接失败

  • 密码错误:确认WiFi密码正确,且长度符合规范(8-63位)

  • 加密类型不匹配:当前工具类默认 WPA2/PSK,若WiFi为其他加密类型(如WPA3),需修改 securityType

  • 配置添加失败:检查SSID是否为空,或设备是否支持该WiFi频率(2.4G/5G)

  • 权限缺失:确认所有WiFi相关权限已配置并申请成功

6.3 API调用报错

  • SDK类型错误:使用了 Public SDK,需切换为 Full SDK

  • API版本不匹配:确保 SDK 版本与设备系统版本一致

6.4 状态监听无响应

  • 未正确注册监听:确认调用了 listenWifiState() 方法

  • 重复注册监听:避免多次调用 listenWifiState(),页面销毁时需取消监听

七、注意事项

  • 本代码仅适用于 OpenHarmony Full SDK,Public  SDK 不支持相关 API,请勿混用。

  • WiFi 操作需在 UIAbility 或 Page 上下文下执行,避免在非UI线程调用。

  • 连接WiFi时,若该WiFi已添加过配置,可先调用 wifiManager.removeDeviceConfig() 删除旧配置,再重新添加连接。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐