作者:張呈
前言
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密碼生成二維碼分享
效果展示
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
- 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"
}
]
- 找到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"
]
- 儲存修改以後,再使用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開發技術,歡迎投稿和訂閱,讓我們一起攜手前行共建鴻蒙生态。
本文正在參加物聯網有獎征文活動