#物联网征文# OpenHarmony -ArkUI(ETS)之WiFi简单的连接操作 原创 精华

中软小助手
发布于 2022-8-11 15:37
浏览
5收藏

作者:张呈

前言

WIFI是大家日常必不可少需求,在OpenHarmony的开发中,系统提供了一系列完整的API,在万物互联的这个概念下,相信涉及到wifi功能操作的需求会越来越多,今日分享的是用ets来实现简单的wifi连接操作,可以实现扫描设备附近的wifi并进行连接,结合一些简单的按钮动画,让体验更加流畅。

项目说明

本组件界面搭建基于ArkUI中TS扩展的声明式开发范式,官网官方文档地址:基于TS扩展的声明式开发范式1基于TS扩展的声明式开发范式2

工具版本:DevEco Studio 3.0 Beta4
SDK版本:3.2.2.5(API Version 9 Beta1)

WiFi及WLAN简介

Wi-Fi指的是Wi-Fi联盟的商标,也是一种基于IEEE 802.11标准的无线网络通信技术,目的是改善基于IEEE 802.11标准的无线网络产品之间的互通性。

WLAN的全称是Wireless Local Area Network,中文含义是无线局域网,WLAN的定义有广义和狭义两种:广义上讲WLAN是以各种无线电波(如激光、红外线等)的无线信道来代替有线局域网中的部分或全部传输介质所构成的网络;WLAN的狭义定义是基于IEEE 802.11系列标准,利用高频无线射频(如2.4GHz或5GHz频段的无线电磁波)作为传输介质的无线局域网。

简单来说就是,WLAN是一个网络系统,而Wi-Fi是这个网络系统中的一种技术。所以,WLAN和Wi-Fi之间是包含关系,WLAN包含了Wi-Fi。

Wi-Fi的历史

在了解Wi-Fi之前,先来了解两个组织:电气和电子工程师协会(英文全称Institute of Electrical and Electronics Engineers,简称IEEE)和Wi-Fi联盟(英语全称Wi-Fi Alliance,简称WFA)。

IEEE作为标准组织,早在1990年,就已经成立了802.11工作组来制定无线局域网的相关标准,并在1997年发布了第一个标准802.11-1997。之后每过几年,802.11标准就会升级换代一次,至今已有6代。

而另一个组织,Wi-Fi联盟,其实是一个商业组织。这个联盟最初的目的是为了推动802.11b标准的制定,并在全球范围内推行符合IEEE 802.11标准的产品的兼容认证;到了2000年,该组织采用了“Wi-Fi”一词作为其技术工作的专有名称,同时宣布使用Wi-Fi Alliance作为正式名称,即Wi-Fi联盟,“Wi-Fi”实际上就是这个联盟的商标。

那么“Wi-Fi”具体有什么含义呢?目前有两种说法:第一种说法认为,Wi-Fi指的是无线保真(Wireless Fidelity),类似于音频设备分类:长期高保真或Hi-Fi(High Fidelity);另外一种说法认为,Wi-Fi并没有特别的含义,也没有全称。目前,并没有官方组织明确表明Wi-Fi就是指的Wireless Fidelity。另外,很多时候“Wi-Fi”会被写成“WiFi”或“wifi”,实际这些写法并没有被Wi-Fi联盟认可。

主要功能

  • 点击扫描可用的wifi
  • 输入密码连接选中的wifi
  • 点击按钮将连接的wifi密码生成二维码分享

效果展示

#物联网征文# OpenHarmony -ArkUI(ETS)之WiFi简单的连接操作-鸿蒙开发者社区

wifiScan-example目录结构

|---- wifiScan-example
    |---- src
    |     |---- main        
    |     |------- ets  
    |     |     |---- components  # 组件               
    |     |     |     |---- ImgDialog.ets  # 二维码弹窗组件                        
    |     |     |     |---- ItemView.ets  # ListItem组件  
    |	  |	    |     |---- PwdDialog.ets  # 密码输入弹窗组件  
    |     |     |---- pages  # 库文件夹     
    |	  |	    |     |---- index.ets  # 主界面  
    |     |     |---- utils  # 工具类
    |	  |	    |     |---- Logger.ts  # 日志打印封装类  

相关权限

获取WLAN信息权限:ohos.permission.GET_WIFI_INFO

获取WLAN网络信息权限:ohos.permission.GET_WIFI_INFO_INTERNAL

允许配置WLAN设备权限:ohos.permission.SET_WIFI_INFO

获取WLAN配置信息权限:ohos.permission.GET_WIFI_CONFIG

允许配置WLAN配置权限:ohos.permission.SET_WIFI_CONFIG

允许控制WLAN连接状态权限:ohos.permission.MANAGE_WIFI_CONNECTION

系统权限的配置

由于WIFI相关的操作是属于OpenHarmony系统核心操作,相应的API对普通权限的应用不开放,所以我们使用这些API时,需要进行单独的配置,如果缺少配置,安装时会报权限错误Failed due to grant request permissions failed

  1. config.json中添加相应权限,这里添加的是使用到的所有权限,我这边是把所有权限列出来的,方便直接复制,实际部分权限是没有使用到的,大家可以根据自己项目需求来选择。
 "reqPermissions": [
      {
        "name": "ohos.permission.GET_WIFI_INFO",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.GET_WIFI_INFO_INTERNAL",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.SET_WIFI_INFO",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.GET_WIFI_PEERS_MAC",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.GET_WIFI_LOCAL_MAC",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.GET_WIFI_CONFIG",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.SET_WIFI_CONFIG",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.MANAGE_WIFI_CONNECTION",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.MANAGE_WIFI_HOTSPOT",
        "reason": "request permission"
      },
      {
        "name": "ohos.permission.LOCATION",
        "reason": "request permission"
      }
    ]
  1. 找到SDK目录下面toolchains\x.x.x.x\lib下面的UnsgnedReleasedProfileTemplate.json文件,使用记事本打开,在里面添加如下权限(主要是添加权限级别为system_core的相关权限)。
    "acls": {
        "allowed-acls": [
    "ohos.permission.GET_SENSITIVE_PERMISSIONS",
	"ohos.permission.GET_WIFI_INFO_INTERNAL",
 	"ohos.permission.GET_WIFI_PEERS_MAC",
 	"ohos.permission.MANAGE_WIFI_CONNECTION",
	"ohos.permission.MANAGE_WIFI_HOTSPOT"
        ]
  1. 保存修改以后,再使用DevEco Studio的自动签名功能重新对应用进行签名就可以正常安装了,更多详细的内容,请参考权限定义列表访问控制开发概述

WiFi相关接口

接口 描述
getScanInfos(callback: AsyncCallback<Array<WifiScanInfo>>): void; 扫描wifi
connectToDevice(config: WifiDeviceConfig): boolean; 连接设备
enableWifi(): boolean 打开WLAN
disableWifi(): boolean 关闭WLAN
isWifiActive(): boolean 查询WIFI是否可以使用
getScanInfosSync(): Array<[WifiScanInfo] 获取扫描结果,使用同步方式返回结果
addDeviceConfig(config: WifiDeviceConfig, callback: AsyncCallback<number>): void 添加网络配置,使用callback异步回调

实现步骤

1. 主页面使用Column+Scroll+List布局

 build() {
      Column(){
        Scroll() {
          List() {
            ForEach(this.wifiList, (item, index) => {
              ListItem() {
                ItemView({ wifi: item })
              }
              .onClick(() => {
                Logger.info(TAG, 'wifi click')
                this.selectIndex = index
                this.pswDialogController.open()
              })
            }, item => JSON.stringify(item))
          }
          .layoutWeight(1)
          .divider({ strokeWidth: 1, color: Color.Gray, startMargin: 10, endMargin: 10 })
          .margin(10)

        }
      }
      .height(600)
      .width('90%')
      .margin({top:30})
      .backgroundColor(Color.White)
      .borderRadius(15)
    }
    .height('100%')
    .margin({ top: 15, bottom: 100 })
    .backgroundColor("#A8A8A8")
  }

2. 扫描可用的WiFi

    wifi.getScanInfos((err, result) => {
      let wifiList = []
      if (err) {
        Logger.log(TAG, `scan err: ${JSON.stringify(err)}`)
        callback(wifiList)
        return
      }
      Logger.log(TAG, `scan callback: ${result.length}`)
      for (var i = 0; i < result.length; ++i) {
        wifiList.push({
          ssid: result[i].ssid,
          bssid: result[i].bssid,
          securityType: result[i].securityType,
          rssi: result[i].rssi,
          band: result[i].band,
          frequency: result[i].frequency,
          timestamp: result[i].timestamp,
        })
      }
      callback(wifiList)
    })
  }

3. 输入密码的弹窗

 Column() {
      Text(this.scanInfo.ssid)
        .fontSize(22)
        .width('95%')
      TextInput({ placeholder: '请输入密码' })
        .type(InputType.Password)
        .placeholderColor(Color.Gray)
        .fontSize(19)
        .margin({ top: 15 })
        .width('95%')
        .onChange((value: string) => {
          this.passwd = value
        })
      Row() {
        Button() {
          Text($r('app.string.sure'))
            .fontColor(Color.Blue)
            .fontSize(17)
        }
        .layoutWeight(7)
        .backgroundColor(Color.White)
        .margin(5)
        .onClick(() => {
          this.controller.close()
          this.action(this.scanInfo, this.passwd)
        })

        Text()
          .width(1).height(36)
          .backgroundColor('#8F8F8F')
        Button() {
          Text($r('app.string.cancel'))
            .fontColor(Color.Red)
            .fontSize(18)
        }
        .layoutWeight(8)
        .backgroundColor(Color.White)
        .margin(5)
        .onClick(() => {
          this.controller.close()
        })
      }
      .width('70%')
      .margin({ top: '2%' })
    }
    .padding(15)
  }

4. 连接选中的WiFi

connectNetwork(scanInfo, psw) {
  let deviceConfig: any = {
    ssid: scanInfo.ssid,
    bssid: scanInfo.bssid,
    preSharedKey: psw,
    isHiddenSsid: false,
    securityType: scanInfo.securityType
  }
  if (wifi.connectToDevice(deviceConfig)) {
    prompt.showToast({ message: 'connect success' })
    wifi.addDeviceConfig(deviceConfig)
  } else {
    prompt.showToast({ message: 'connect fail' })
  }
}

5. 分享二维码弹窗

  build() {
    Column() {
      QRCode(this.passwd)
        .width(150)
        .height(this.height)
        .margin({top:50})
        .color(Color.Green)
        Button() {
          Text($r('app.string.cancel'))
            .fontColor(Color.Red)
            .fontSize(18)
        }
        .backgroundColor(Color.White)
        .margin(20)
        .onClick(() => {
          this.controller.close()
        })
    }
    .width('80%')
    .alignItems(HorizontalAlign.Center)

  }

附:按钮及二维码的动画代码

  private animateStart(){
    animateTo({
      duration: 110,
      tempo: 1,
      curve: Curve.Sharp,
      delay: 50,
      iterations: 1,
      playMode: PlayMode.Normal,
      onFinish: () => {
      }
    }, () => {
      this.height = 150;
    });
  }

  private animateEnd(){
    animateTo({
      duration: 300,
      tempo: 1,
      curve: Curve.Linear,
      delay: 200,
      iterations: 1,
      playMode: PlayMode.Normal,
      onFinish: () => {
        this.wifiModel.getScanInfos((result) => {
          this.wifiList = result
        })
        this.scanWifi = '扫描WIFI';
      }
    }, () => {
      this.btnWidth = 120;
      this.btnHeight = 120;
      this.borderRadius = 15;
    });
  }

项目源码

OpenHarmony -ArkUI(ETS)之WiFi简单的连接操作

总结

以上就是这次的全部内容,最终效果如动图所示。整个布局界面非常简单,但是能够实现WIFI连接的基本功能,其实WIFI功能提供的API中,还有很多能够扩展的地方,后续我也会继续学习,希望能更进一步的完善这一块的功能,写出更加优美流畅的示例。欢迎大家一起研究讨论,希望本次内容能够对大家有所帮助。

附 参考文档

什么是WiFi?

权限定义列表

访问控制开发概述

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

本文正在参加物联网有奖征文活动

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
10
收藏 5
回复
举报
5条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

好详细的讲解,这个工具让我想起了早些年大火的万能钥匙

已于2022-8-11 15:49:58修改
1
回复
2022-8-11 15:49:50
FlashinMiami
FlashinMiami 回复了 红叶亦知秋
好详细的讲解,这个工具让我想起了早些年大火的万能钥匙

还需要加个保存功能和联网分享功能

1
回复
2022-8-11 17:12:45
青舟321
青舟321

很多时候“Wi-Fi”会被写成“WiFi”或“wifi”,实际这些写法并没有被Wi-Fi联盟认可。

可以拿去给朋友科普了

回复
2022-8-12 17:41:55
HUAWEI_Engineer
HUAWEI_Engineer

学习一下

 

回复
2022-8-13 15:18:12
物联风景
物联风景

不错不错,先收藏了

回复
2022-8-14 09:34:41
回复
    相关推荐