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

  1. 手机移动数据已经开启;
  2. 手机至少插入了一张 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();
posted @ 2026-09-07 14:55  带头大哥d小弟  阅读(7)  评论(0)    收藏  举报