1. Wifi热点简介

Wifi热点是移动设备接入网络的重要形式,特别是在不具备固定网络接入点的情况下,可以通过Wifi热点灵活方便的接入网络,因此在日常生活中具有广泛的应用。鸿蒙系统也提供了方便的Wifi管理API,支持热点扫描,热点连接等功能,相关的能力归属于系统相关Kit开放能力中的Connectivity Kit(短距通信服务),使用如下的代码导入模块:

import { wifiManager } from '@kit.ConnectivityKit';

本文将通过一个示例演示扫描Wifi热点以及连接指定热点的功能,相关的主要Wifi能力接口如下所示:

//返回扫描到的热点列表
function getScanInfoList(): Array<WifiScanInfo>;

//查询WLAN信号强度。
function getSignalLevel(rssi: number, band: number): number;

//添加候选网络配置
function addCandidateConfig(config: WifiDeviceConfig): Promise<number>;

//连接到自己添加的候选网络(如果当前已经连接到热点,需要先断开连接)。
function connectToCandidateConfig(networkId: number): void;

2. Wifi热点扫描及连接演示

本示例运行后的界面如图所示:

单击“扫描热点”按钮,会扫描附近的热点,界面如下所示:

这里列出了热点的名称、是否加密、网络制式以及信号强度。要连接某一个特定热点,单击热点后面的"连接"按钮即可,不过要注意的是,如果当前手机已经连接了一个热点,需要先断开连接才能连接新的热点,假设已经断开了Wifi连接,在某一个标识加密的热点后面单击"连接"按钮,会出现密码输入框,输入密码后,再单击"连接"按钮,会出现“连接至指定的候选WLAN”的弹出窗口,如图所示:

单击弹出窗口的"连接"按钮,即可连接到指定的热点,如图所示:

3. Wifi热点扫描及连接示例编写

下面详细介绍创建该示例的步骤。
步骤1:创建Empty Ability项目。

步骤2:在module.json5配置文件加上对权限的声明:

"requestPermissions": [
      {
        "name": "ohos.permission.GET_WIFI_INFO"
      },
      {
        "name": "ohos.permission.SET_WIFI_INFO"
      }
    ]

这里添加了读取和设置Wifi配置的权限。

步骤3:添加WifiHotspotItem.ets文件,该文件定义了显示Wifi热点信息的子组件,代码如下:

import { wifiManager } from '@kit.ConnectivityKit';

@ComponentV2
export struct WifiHotspotItem {
  @Param @Require WifiInfo: wifiManager.WifiScanInfo
  @Param @Require connectCallback: (item: wifiManager.WifiScanInfo, password: string) => void
  @Local showPassword: boolean = false
  @Local password: string = ""

  build() {
    Column() {
      Flex({ justifyContent: FlexAlign.End, alignItems: ItemAlign.Center }) {
        Text(this.WifiInfo.ssid)
          .width(120)
          .flexGrow(1)

        Text(this.WifiInfo.securityType == wifiManager.WifiSecurityType.WIFI_SEC_TYPE_OPEN ? "开放" : "加密")
          .width(40)

        Text(this.WifiInfo.band == 1 ? "2.5G" : "5G")
          .width(40)

        Rating({ rating: wifiManager.getSignalLevel(this.WifiInfo.rssi, this.WifiInfo.band), indicator: true })
          .stars(5)
          .width(80)

        Button("连接")
          .onClick(() => {
            if (this.WifiInfo.securityType != wifiManager.WifiSecurityType.WIFI_SEC_TYPE_OPEN) {
              this.showPassword = true
            } else {
              this.showPassword = false
            }
            if (this.showPassword && this.password == "") {
              return
            }
            this.connectCallback(this.WifiInfo, this.password)
          })
          .width(60)
          .fontSize(12)
      }
      .width('100%')

      Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
        Text("请输入wifi密码")
          .width(150)

        TextInput({ text: this.password })
          .onChange((value) => {
            this.password = value
          })
          .width(100)
          .type(InputType.Password)
          .flexGrow(1)
          .fontSize(11)
      }
      .width('100%')
      .visibility(this.showPassword ? Visibility.Visible : Visibility.None)
    }
    .width('100%')
    .padding(5)
  }
}

步骤4:在Index.ets文件里添加如下的代码:

import { wifiManager } from '@kit.ConnectivityKit';
import { WifiHotspotItem } from './WifiHotspotItem';

@Entry
@ComponentV2
struct Index {
  //Wifi热点列表
  @Local wifiHotspotParamList: wifiManager.WifiScanInfo[] = []

  build() {
    Row() {
      Column() {
        Text("Wifi热点管理")
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .width('100%')
          .textAlign(TextAlign.Center)
          .padding(10)

        Flex({ justifyContent: FlexAlign.End, alignItems: ItemAlign.Center }) {
          Button("扫描热点")
            .onClick(() => {
              this.wifiHotspotParamList = wifiManager.getScanInfoList().sort((a, b) => {
                return wifiManager.getSignalLevel(b.rssi, b.band) - wifiManager.getSignalLevel(a.rssi, a.band)
              })
            })
            .width(120)
            .fontSize(14)
        }
        .width('100%')
        .padding(5)

        List({ space: 10, initialIndex: 0 }) {
          ForEach(this.wifiHotspotParamList, (item: wifiManager.WifiScanInfo) => {
            if (item.ssid != "") {
              ListItem() {
                WifiHotspotItem({ WifiInfo: item, connectCallback: this.connectWifiHotspot })
              }
            }
          })
        }.width('100%')
        .padding(5)
      }
      .width('100%')
      .justifyContent(FlexAlign.Start)
      .height('100%')
    }
    .height('100%')
  }

  //执行连接的方法
  async connectWifiHotspot(wifiInfo: wifiManager.WifiScanInfo, password: string): Promise<void> {
    if (wifiManager.isConnected()) {
      AlertDialog.show({
        title: "提示",
        message: "请先断开Wifi连接",
        confirm: {
          value: '确定',
          action: () => {
          }
        }
      })
      return
    }

    let config: wifiManager.WifiDeviceConfig = {
      ssid: wifiInfo.ssid,
      preSharedKey: password,
      securityType: wifiInfo.securityType
    }

    let netId = await wifiManager.addCandidateConfig(config)
    wifiManager.connectToCandidateConfig(netId)
  }
}

步骤5:编译运行,可以使用模拟器或者真机。

步骤6:按照本节第2部分“Wifi热点扫描及连接演示”操作即可。

4. 代码分析

本示例主要有两点需要注意,第一点是关于热点的信号强度级别,虽然扫描时得到了热点的信号强度属性rssi,但是这个属性不适合按照强度级别来表示,本示例是通过getSignalLevel函数来查询得到信号强度对应的信号强度级别的;另外一点是连接到热点,系统并不是直接连接热点的,而是先把热点添加为候选网络,得到网络配置ID,然后再通过该ID连接到指定的热点网络,代码如下所示:

let config: wifiManager.WifiDeviceConfig = {
      ssid: wifiInfo.ssid,
      preSharedKey: password,
      securityType: wifiInfo.securityType
    }

    let netId = await wifiManager.addCandidateConfig(config)
    wifiManager.connectToCandidateConfig(netId)

(本文作者原创,除非明确授权禁止转载)

本文源码地址:

https://gitee.com/zl3624/harmonyos_network_samples/tree/maste...

本系列源码地址:

https://gitee.com/zl3624/harmonyos_network_samples


长弓三石
1 声望0 粉丝