WifiConnectManager 使用说明
WifiConnectManager 使用说明
WifiConnectManager 主要用来管理当前应用使用哪一种网络:
- Wi-Fi 网络;
- 蜂窝移动数据,也就是手机流量;
- 将指定网络绑定到当前应用;
- 判断移动数据是否开启;
- 判断手机是否插入 SIM 卡。
1. 获取单例对象
这个类使用单例模式,不能直接 new,统一通过 getInstance() 获取。
import { WifiConnectManager } from '@ohos/base';
const manager = WifiConnectManager.getInstance();
在组件中可以这样定义:
@Local manager: WifiConnectManager =
WifiConnectManager.getInstance();
2. 判断移动数据是否可用
调用下面的方法:
const enabled = await manager.isMobileDataEnabled();
只有同时满足以下条件时,返回值才是 true:
- 手机移动数据已经开启;
- 手机至少插入了一张 SIM 卡。
源码逻辑:
public async isMobileDataEnabled(): Promise<boolean> {
return await data.isCellularDataEnabled() &&
this.isSimCardInserted();
}
完整使用示例:
const manager = WifiConnectManager.getInstance();
if (await manager.isMobileDataEnabled()) {
console.info('可以使用手机流量');
} else {
console.info('移动数据不可用');
}
注意:返回 true 只能说明移动数据具备使用条件,不代表当前一定有信号,也不代表一定可以访问互联网。
3. 判断是否插入 SIM 卡
调用:
const hasSimCard = manager.isSimCardInserted();
内部会遍历手机的所有卡槽:
public isSimCardInserted(): boolean {
const maxSimCount = sim.getMaxSimCount();
for (let i = 0; i < maxSimCount; i++) {
try {
if (sim.hasSimCardSync(i)) {
return true;
}
} catch (error) {
console.error(JSON.stringify(error));
}
}
return false;
}
4. 监听并绑定 Wi-Fi
调用:
manager.startListenNetChange(true);
参数含义:
startListenNetChange(true)
表示当前应用优先使用 Wi-Fi。
简单示例:
import { WifiConnectManager, WifiManagerUtil } from '@ohos/base';
const manager = WifiConnectManager.getInstance();
if (WifiManagerUtil.isWifiActive()) {
manager.startListenNetChange(true);
}
当 Wi-Fi 网络触发下面的事件时,类会尝试将 Wi-Fi 设置为当前应用使用的网络:
netAvailable:网络可用;netLost:网络丢失。
5. 监听并绑定手机流量
调用:
manager.startListenNetChange(false);
参数含义:
startListenNetChange(false)
表示当前应用优先使用蜂窝移动数据。
使用前建议先检查移动数据是否可用:
const manager = WifiConnectManager.getInstance();
if (await manager.isMobileDataEnabled()) {
manager.startListenNetChange(false);
} else {
console.info('当前无法使用手机流量');
}
6. Wi-Fi 和流量的选择逻辑
项目中通常优先使用普通 Wi-Fi,Wi-Fi 不可用时再使用手机流量:
async function prepareNetwork(): Promise<boolean> {
const manager = WifiConnectManager.getInstance();
// 优先使用 Wi-Fi
if (WifiManagerUtil.isWifiActive()) {
manager.startListenNetChange(true);
return true;
}
// Wi-Fi 不可用时使用手机流量
if (await manager.isMobileDataEnabled()) {
manager.startListenNetChange(false);
return true;
}
return false;
}
调用:
const canRequest = await prepareNetwork();
if (!canRequest) {
console.error('当前没有可用网络');
return;
}
// 网络准备完成后执行请求
this.loadData();
7. 绑定 Wi-Fi 的原理
Wi-Fi 网络可用时,内部会执行以下流程:
获取系统默认网络
-> 绑定默认网络
-> 获取所有网络
-> 找到 Wi-Fi 网络
-> 将 Wi-Fi 网络绑定给当前应用
核心逻辑可以理解为:
await connection.setAppNet(connection.getDefaultNetSync());
const nets = await connection.getAllNets();
nets.forEach(async (net) => {
const capabilities = await connection.getNetCapabilities(net);
if (capabilities.bearerTypes.length > 0 &&
capabilities.bearerTypes[0] ===
connection.NetBearType.BEARER_WIFI) {
await connection.setAppNet(net);
}
});
8. 绑定蜂窝移动数据的原理
绑定流量前会先检查移动数据和 SIM 卡状态:
const enabled = await this.isMobileDataEnabled();
if (!enabled) {
ToastUtil.showToast($r('app.string.Telephony_error'));
return;
}
然后从所有网络中找到蜂窝网络,并绑定到当前应用:
const nets = await connection.getAllNets();
nets.forEach(async (net) => {
const capabilities = await connection.getNetCapabilities(net);
if (capabilities.bearerTypes.length > 0 &&
capabilities.bearerTypes[0] ===
connection.NetBearType.BEARER_CELLULAR) {
await connection.setAppNet(net);
}
});
9. 取消应用网络绑定
调用:
manager.cancelBind();
该方法会将当前应用的网络绑定恢复为系统默认状态。
适合在以下场景调用:
- 页面退出;
- 固件下载完成;
- 不再需要固定使用某条网络;
- 从相机 Wi-Fi 切换回普通网络;
- 用户退出当前业务流程。
示例:
aboutToDisappear() {
WifiConnectManager.getInstance().cancelBind();
}
10. 固件升级中的使用方式
固件升级通常需要访问互联网,不能走相机 Wi-Fi,因此可以根据网络状态选择网络:
async startGetFirm() {
const manager = WifiConnectManager.getInstance();
if (this.netBean.isNetworkAvailable &&
WifiManagerUtil.isWifiActive() &&
!this.netBean.isConnectCamera) {
// 当前连接的是普通 Wi-Fi
manager.startListenNetChange(true);
} else if (await manager.isMobileDataEnabled()) {
// Wi-Fi 不可用时使用手机流量
manager.startListenNetChange(false);
} else {
this.nowLateState = FirmwareUpdateState.NETWORK_ERROR;
return;
}
await this.checkFirmware();
}
基本流程:
普通 Wi-Fi 可用
-> 绑定 Wi-Fi
普通 Wi-Fi 不可用
-> 判断移动数据
-> 绑定蜂窝数据
两者都不可用
-> 提示网络错误
11. Web 页面中的使用方式
网页加载前,也可以先准备网络:
async loadWebPage() {
const manager = WifiConnectManager.getInstance();
if (this.netBean.isNetworkAvailable &&
WifiManagerUtil.isWifiActive() &&
!this.netBean.isConnectCamera) {
manager.startListenNetChange(true);
} else if (await manager.isMobileDataEnabled()) {
manager.startListenNetChange(false);
} else {
this.nowLateState = false;
return;
}
this.loadWebView();
}
适合以下场景:
- 固件信息查询;
- 帮助页面;
- 在线网页;
- 云端数据请求;
- 不希望请求走相机 Wi-Fi 的场景。
12. 和 WifiManagerUtil 的区别
项目里有两个容易混淆的类。
WifiManagerUtil
WifiManagerUtil 主要管理手机 Wi-Fi 本身和相机热点连接:
- 判断 Wi-Fi 是否打开;
- 获取 Wi-Fi 网关;
- 获取 Wi-Fi 扫描列表;
- 调用
startScan(); - 连接相机 Wi-Fi 热点;
- 删除 Wi-Fi 配置。
示例:
WifiManagerUtil.startScan();
await WifiManagerUtil.connectNetwork(
ssid,
password,
securityType,
(result) => {
console.info(`Wi-Fi connection result: ${result}`);
}
);
WifiConnectManager
WifiConnectManager 主要管理当前应用使用哪条网络:
- 监听 Wi-Fi 网络;
- 监听蜂窝网络;
- 将 Wi-Fi 绑定给当前应用;
- 将蜂窝网络绑定给当前应用;
- 判断移动数据和 SIM 卡;
- 取消应用网络绑定。
简单记忆:
WifiManagerUtil
= 管理手机 Wi-Fi 和相机热点
WifiConnectManager
= 管理当前应用使用 Wi-Fi 还是手机流量
13. 当前实现的注意事项
13.1 重复调用会重复注册监听
当前 startListenNetChange() 每调用一次,都会重新创建 Wi-Fi 和蜂窝网络监听器:
manager.startListenNetChange(true);
manager.startListenNetChange(true);
manager.startListenNetChange(false);
可能导致:
- 重复注册网络监听;
- 一个网络事件触发多次;
- 重复调用
setAppNet(); - 页面多次进入后监听器越来越多;
- 重复打印日志或重复发起请求。
当前类没有保存网络监听对象,也没有提供真正的监听注销方法。因此使用时要避免在多个生命周期里反复调用。
13.2 isWifi 是全局状态
类内部只有一个网络类型标记:
private isWifi: boolean = true;
调用下面的代码时,第二次调用会覆盖第一次的选择:
manager.startListenNetChange(true);
manager.startListenNetChange(false);
可能出现的情况:
页面 A 想使用 Wi-Fi
页面 B 想使用手机流量
最后一次调用覆盖前面的选择
建议统一在一个地方决定网络类型,不要让多个页面同时管理网络绑定。
13.3 netLost 当前也会触发绑定逻辑
当前实现中,无论收到 netAvailable 还是 netLost,都会根据 isWifi 调用绑定方法:
netConnectionWifi.on('netLost', () => {
if (this.isWifi) {
this.bindWifiWhenConnected();
} else {
this.bindCellularWhenConnected();
}
});
这可能导致网络已经断开时仍然尝试绑定对应网络。排查网络切换问题时,需要重点关注这里的日志和调用结果。
13.4 这个类没有网络请求回调
startListenNetChange() 返回值是 void,它只负责注册监听和发起绑定,不会告诉调用方“绑定已经完成”。
所以不要把下面的代码理解为网络已经立即切换成功:
manager.startListenNetChange(true);
this.loadData();
如果请求对网络切换时机要求较高,需要增加明确的绑定完成回调,或者延迟请求并再次检查网络状态。
14. 日常快速使用模板
import { WifiConnectManager, WifiManagerUtil } from '@ohos/base';
export async function prepareAppNetwork(): Promise<boolean> {
const manager = WifiConnectManager.getInstance();
// 优先使用普通 Wi-Fi
if (WifiManagerUtil.isWifiActive()) {
manager.startListenNetChange(true);
return true;
}
// Wi-Fi 不可用时使用手机流量
if (await manager.isMobileDataEnabled()) {
manager.startListenNetChange(false);
return true;
}
return false;
}
调用:
const ready = await prepareAppNetwork();
if (!ready) {
ToastUtil.showToast('当前没有可用网络');
return;
}
// 执行网络请求
15. 快速记忆
// 获取单例
const manager = WifiConnectManager.getInstance();
// 判断是否插入 SIM 卡
manager.isSimCardInserted();
// 判断移动数据是否可用
await manager.isMobileDataEnabled();
// 监听并绑定 Wi-Fi
manager.startListenNetChange(true);
// 监听并绑定手机流量
manager.startListenNetChange(false);
// 取消当前应用的网络绑定
manager.cancelBind();
浙公网安备 33010602011771号