OpenHarmony Full SDK WiFi 连接开发文档
一、文档概述
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() 删除旧配置,再重新添加连接。
更多推荐
所有评论(0)