在eTS中WLAN的基本使用,包括禁用和啟用WLAN、WLAN掃描和獲取掃描結(jié)果、WLAN狀態(tài)監(jiān)聽、WiFi連接狀態(tài)監(jiān)聽、獲取IP信息、獲取國家碼、判斷設(shè)備是否支持WLAN相關(guān)特性。
樣例展示

WLAN(僅對系統(tǒng)應(yīng)用開放)
介紹
本示例通過[@ohos.wifiManager] 相關(guān)API實現(xiàn)wlan激活和關(guān)閉、掃描和連接WIFI等功能。
效果預(yù)覽

使用說明
- 啟動應(yīng)用后會判斷WLAN是否激活,如果是激活狀態(tài),會掃描并展示可用WiFi列表,同時獲取已連接WiFi信息并展示;
 - 點擊界面的Switch開關(guān)可以禁用和激活WLAN,界面會監(jiān)聽WLAN狀態(tài)掃描可用WiFi列表,也會監(jiān)聽WiFi連接狀態(tài)展示已連接WiFi;
 - 點擊可用WLAN列表中的WLAN信息,可以連接WiFi,如果是加密類型,會彈窗輸入密碼后連接;
 - 點擊首頁右上角的關(guān)于圖標,進入關(guān)于界面,展示獲取的IP信息、國家碼和支持WLAN相關(guān)特性信息。
 
具體實現(xiàn)
- wlan激活和關(guān)閉功能:點擊首頁的切換按鈕,如果是打開,使用wifi.enableWifi()開啟wifi;如果是關(guān)閉,則使用wifi.disconnect()斷開wifi, 然后使用wifi.disableWifi()關(guān)閉wifi, 源碼參考:[Index.ets] 。
 
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import wifi from '@ohos.wifiManager'
import { AvailableWifi } from '../component/AvailableWifi'
import Logger from '../model/Logger'
import { TitleBar } from '../component/TitleBar'
import { WifiModel, WifiType } from '../model/WifiModel'
const TAG = 'Index'
@Entry
@Component
struct Index {
  private wifiModel: WifiModel = new WifiModel()
  private linkedInfo: wifi.WifiLinkedInfo = null
  @State isLinked: boolean = false
  @State isSwitchOn: boolean = false
  // 掃描wifi
  async scan() {
    // 獲取有關(guān)Wi-Fi連接的信息,存入linkedInfo
    await this.getLinkedInfo()
    // 不停地掃描wifi
    let result: Array< WifiType > = await this.wifiModel.getScanInfos()
    if (this.isSwitchOn) {
      AppStorage.SetOrCreate('wifiList', result)
      setTimeout(async () = > {
        await this.scan()
      }, 3000)
    }
  }
  // 獲取有關(guān)Wi-Fi連接的信息,存入linkedInfo
  async getLinkedInfo() {
    try {
      let wifiLinkedInfo = await wifi.getLinkedInfo()
      if (wifiLinkedInfo === null || wifiLinkedInfo.bssid === '') {
        this.isLinked = false
        this.linkedInfo = null
        return
      }
      this.isLinked = true
      this.linkedInfo = wifiLinkedInfo
    } catch (err) {
      Logger.info(`getLinkedInfo failed err is ${JSON.stringify(err)}`)
    }
  }
  // 監(jiān)聽wifi的變化
  addListener() {
    // 連接狀態(tài)改變時,修改連接信息
    wifi.on('wifiConnectionChange', async state = > {
      Logger.log(TAG, `wifiConnectionChange: ${state}`)
      await this.getLinkedInfo()
    })
    // wifi狀態(tài)改變時,先清空wifi列表,然后判斷是否是開啟狀態(tài),如果是就掃描
    wifi.on('wifiStateChange', state = > {
      Logger.log(TAG, `wifiStateLisener state: ${state}`)
      AppStorage.SetOrCreate('wifiList', [])
      if (state === 1) { // 1: wifi is enable, 0:wifi is disable
        this.scan()
      }
    })
  }
  aboutToAppear() {
    // 如果wifi是開的,就記錄下狀態(tài),然后掃描wifi,并獲取連接信息
    if (wifi.isWifiActive()) {
      Logger.log(TAG, 'wifi is active')
      this.isSwitchOn = true
      wifi.scan()
      this.scan()
      this.getLinkedInfo()
    }
    // 啟動監(jiān)聽
    this.addListener()
  }
  build() {
    Column() {
      TitleBar()
      Row() {
        Text($r('app.string.wlan'))
          .fontSize(22)
          .fontWeight(FontWeight.Bold)
          .height(40)
        Column() {
          Toggle({ type: ToggleType.Switch, isOn: this.isSwitchOn })
            .id('switch')
            .onChange((isOn: boolean) = > {
              Logger.log(`LSQ: wifi swtich is: ${isOn}`)
              AppStorage.SetOrCreate('wifiList', [])
              try {
                // 如果是打開狀態(tài),記錄狀態(tài),打開網(wǎng)絡(luò),開始掃描
                if (isOn) {
                  this.isSwitchOn = true
                  wifi.enableWifi()
                  return
                } else {
                  // 記錄狀態(tài),斷開網(wǎng)絡(luò)禁用網(wǎng)絡(luò)
                  this.isSwitchOn = false
                  this.isLinked = false
                  wifi.disconnect()
                  wifi.disableWifi()
                }
              } catch (error) {
                Logger.error(TAG, `failed,code:${JSON.stringify(error.code)},message:${JSON.stringify(error.message)}`)
              }
            })
        }
      }
      .width('100%')
      .padding({ left: 16, right: 16 })
      if (this.isLinked && this.isSwitchOn) {
        Column() {
          Text($r('app.string.connected'))
            .fontSize(22)
            .width('100%')
          Row() {
            Text(this.linkedInfo.ssid)
              .fontSize(20)
              .fontColor(Color.Black)
              .layoutWeight(1)
            Text($r('app.string.connected'))
              .fontSize(18)
              .fontColor(Color.Black)
          }
          .width('100%')
          .padding(10)
          .margin({ left: 16, right: 16 })
          .border({ radius: 15, color: Color.Gray, width: 1 })
          .backgroundColor(Color.White)
        }
        .width('100%')
        .padding({ left: 16, right: 16 })
      }
      if (this.isSwitchOn) {
        AvailableWifi({ linkedInfo: this.linkedInfo })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_bg'))
  }
  aboutToDisappear() {
    wifi.off('wifiConnectionChange')
    wifi.off('wifiStateChange')
  }
}
- wifi的連接、掃描、獲取詳細信息等功能封裝在WifiModel模塊中,源碼參考:[WifiModel.ets]。
 
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import prompt from '@ohos.promptAction'
import wifi from '@ohos.wifiManager'
import Logger from '../model/Logger'
const TAG: string = 'WiFiModel'
export type WifiType = {
  ssid: string,
  bssid: string,
  securityType: wifi.WifiSecurityType,
  rssi: number,
  band: number,
  frequency: number,
  timestamp: number
}
export class WifiModel {
  async getScanInfos(): Promise< Array< WifiType >> {
    Logger.log(TAG, 'scanWifi begin')
    let wifiList: Array< WifiType > = []
    let result: Array< wifi.WifiScanInfo > = []
    try {
      result = await wifi.getScanResults()
    } catch (err) {
      Logger.log(TAG, `scan info err: ${JSON.stringify(err)}`)
      return wifiList
    }
    Logger.log(TAG, `scan info call back: ${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
      })
    }
    return wifiList
  }
  connectNetwork(scanInfo: wifi.WifiScanInfo, psw) {
    prompt.showToast({ message: 'connecting', duration: 5000 })
    Logger.debug(TAG, `connectNetwork bssid=${scanInfo.bssid}`)
    // 這里因為api問題,需要聲明為any,已提單
    let deviceConfig: any = {
      ssid: scanInfo.ssid,
      bssid: scanInfo.bssid,
      preSharedKey: psw,
      isHiddenSsid: false,
      securityType: scanInfo.securityType
    }
    try {
      wifi.connectToDevice(deviceConfig)
      Logger.debug(TAG, `connectToDevice success`)
    } catch (err) {
      Logger.debug(TAG, `connectToDevice fail err is ${JSON.stringify(err)}`)
    }
    try {
      wifi.addDeviceConfig(deviceConfig)
    } catch (err) {
      Logger.debug(TAG, `addDeviceConfig fail err is ${JSON.stringify(err)}`)
    }
  }
  resolveIP(ip) {
    let address: string = ip.toString()
    if (address === '0') {
      return '00:00:000:000'
    }
    address.substring(0, 2)
    return `${address.substring(0, 2)}:${address.substring(2, 4)}:${address.substring(4, 7)}:${address.substring(7, 10)}`
  }
  getIpInfo() {
    let ipInfoList = []
    let ipInfo = wifi.getIpInfo()
    Logger.info(`${TAG} getIpInfo=${JSON.stringify(ipInfo)}`)
    ipInfoList.push({ key: $r('app.string.ip_address'), value: this.resolveIP(ipInfo.ipAddress) })
    ipInfoList.push({ key: $r('app.string.gate_way'), value: this.resolveIP(ipInfo.gateway) })
    ipInfoList.push({ key: $r('app.string.net_mask'), value: this.resolveIP(ipInfo.netmask) })
    ipInfoList.push({ key: $r('app.string.primary_dns'), value: this.resolveIP(ipInfo.primaryDns) })
    ipInfoList.push({ key: $r('app.string.second_dns'), value: this.resolveIP(ipInfo.secondDns) })
    ipInfoList.push({ key: $r('app.string.server_ip'), value: this.resolveIP(ipInfo.serverIp) })
    ipInfoList.push({ key: $r('app.string.lease_duration'), value: ipInfo.leaseDuration.toString() })
    return ipInfoList
  }
  getCountryCode() {
    let countryCodeList = []
    let countryCode = wifi.getCountryCode()
    countryCodeList.push({ key: $r('app.string.country_code'), value: countryCode })
    return countryCodeList
  }
  getFeatureSupport() {
    let featureSupportedList = []
    featureSupportedList.push({
      key: $r('app.string.infrastructure_feature'),
      value: wifi.isFeatureSupported(0x0001).toString()
    })
    featureSupportedList.push({ key: $r('app.string.ghz_feature'), value: wifi.isFeatureSupported(0x0002).toString() })
    featureSupportedList.push({
      key: $r('app.string.gas_anqp_feature'),
      value: wifi.isFeatureSupported(0x0004).toString()
    })
    featureSupportedList.push({ key: $r('app.string.wifi_direct'), value: wifi.isFeatureSupported(0x0008).toString() })
    featureSupportedList.push({ key: $r('app.string.soft_ap'), value: wifi.isFeatureSupported(0x0010).toString() })
    featureSupportedList.push({ key: $r('app.string.wifi_aware'), value: wifi.isFeatureSupported(0x0040).toString() })
    return featureSupportedList
  }
}
wifi的連接功能:點擊wifi列表中加密的wifi,并在彈窗中輸入密碼后,會在[AvailableWifi.ets] 中通過WifiModule.connectNetwork()調(diào)用wifi.connectToDevice()連接wifi,如圖中的 連接wifi 。
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import prompt from '@ohos.promptAction'
import Logger from '../model/Logger'
import { PswDialog } from '../component/PswDialog'
import { WifiModel } from '../model/WifiModel'
import { WifiView } from '../component/WifiView'
import WifiDataSource from '../component/BasicDataSource'
import wifi from '@ohos.wifiManager'
const TAG = 'AvailableWiFi'
let self = null
@Component
export struct AvailableWifi {
  private wifiModel = new WifiModel()
  private linkedInfo: wifi.WifiLinkedInfo = null
  @StorageLink('wifiList') @Watch('wifiListRefresh') wifiList: Array< wifi.WifiScanInfo > = []
  @State wifiDataResource: WifiDataSource = new WifiDataSource(this.wifiList)
  @State scanInfo: wifi.WifiScanInfo = undefined
  private pswDialogController: CustomDialogController = new CustomDialogController({
    builder: PswDialog({ scanInfo: $scanInfo, action: this.onAccept }),
    autoCancel: true
  })
  build() {
    List() {
      ListItem() {
        Row() {
          Text($r('app.string.available_wlan'))
            .fontSize(22)
            .layoutWeight(1)
        }
        .id('validWlan')
        .width('100%')
      }
      LazyForEach(this.wifiDataResource, (item, index) = > {
        ListItem() {
          WifiView({ wifi: item })
        }
        .id(`Wifi${index}`)
        .onClick(() = > {
          Logger.info(TAG, 'wifi click')
          this.scanInfo = item
          if (this.linkedInfo !== null && item.ssid === this.linkedInfo.ssid) {
            prompt.showToast({ message: 'this wifi is connected' })
            return
          }
          if (item.securityType === 0 || item.securityType === 1) {
            this.wifiModel.connectNetwork(item, '')
            return
          }
          this.pswDialogController.open()
        })
      }, item = > JSON.stringify(item))
    }
    .width('100%')
    .height('100%')
    .padding({ left: 16, right: 16 })
    .layoutWeight(1)
    .divider({ strokeWidth: 1, color: Color.Gray, startMargin: 10, endMargin: 10 })
    .margin({ top: 10 })
  }
  onAccept(scanInfo, psw) {
    Logger.info(TAG, 'connect wifi')
    self.wifiModel.connectNetwork(scanInfo, psw)
  }
  aboutToAppear() {
    self = this
  }
  wifiListRefresh() {
    this.wifiDataResource['dataArray'] = this.wifiList
    this.wifiDataResource.notifyDataReload()
  }
}
wifi的掃描功能:進入[Index.ets]后就會間歇性的調(diào)用wifi.scan()開啟掃描,然后通過WifiModel模塊中的getScanInfos()調(diào)用wifi.getScanResults()來獲取掃描的結(jié)果,如圖中的 主頁 。
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import wifi from '@ohos.wifiManager'
import { AvailableWifi } from '../component/AvailableWifi'
import Logger from '../model/Logger'
import { TitleBar } from '../component/TitleBar'
import { WifiModel, WifiType } from '../model/WifiModel'
const TAG = 'Index'
@Entry
@Component
struct Index {
  private wifiModel: WifiModel = new WifiModel()
  private linkedInfo: wifi.WifiLinkedInfo = null
  @State isLinked: boolean = false
  @State isSwitchOn: boolean = false
  // 掃描wifi
  async scan() {
    // 獲取有關(guān)Wi-Fi連接的信息,存入linkedInfo
    await this.getLinkedInfo()
    // 不停地掃描wifi
    let result: Array< WifiType > = await this.wifiModel.getScanInfos()
    if (this.isSwitchOn) {
      AppStorage.SetOrCreate('wifiList', result)
      setTimeout(async () = > {
        await this.scan()
      }, 3000)
    }
  }
  // 獲取有關(guān)Wi-Fi連接的信息,存入linkedInfo
  async getLinkedInfo() {
    try {
      let wifiLinkedInfo = await wifi.getLinkedInfo()
      if (wifiLinkedInfo === null || wifiLinkedInfo.bssid === '') {
        this.isLinked = false
        this.linkedInfo = null
        return
      }
      this.isLinked = true
      this.linkedInfo = wifiLinkedInfo
    } catch (err) {
      Logger.info(`getLinkedInfo failed err is ${JSON.stringify(err)}`)
    }
  }
  // 監(jiān)聽wifi的變化
  addListener() {
    // 連接狀態(tài)改變時,修改連接信息
    wifi.on('wifiConnectionChange', async state = > {
      Logger.log(TAG, `wifiConnectionChange: ${state}`)
      await this.getLinkedInfo()
    })
    // wifi狀態(tài)改變時,先清空wifi列表,然后判斷是否是開啟狀態(tài),如果是就掃描
    wifi.on('wifiStateChange', state = > {
      Logger.log(TAG, `wifiStateLisener state: ${state}`)
      AppStorage.SetOrCreate('wifiList', [])
      if (state === 1) { // 1: wifi is enable, 0:wifi is disable
        this.scan()
      }
    })
  }
  aboutToAppear() {
    // 如果wifi是開的,就記錄下狀態(tài),然后掃描wifi,并獲取連接信息
    if (wifi.isWifiActive()) {
      Logger.log(TAG, 'wifi is active')
      this.isSwitchOn = true
      wifi.scan()
      this.scan()
      this.getLinkedInfo()
    }
    // 啟動監(jiān)聽
    this.addListener()
  }
  build() {
    Column() {
      TitleBar()
      Row() {
        Text($r('app.string.wlan'))
          .fontSize(22)
          .fontWeight(FontWeight.Bold)
          .height(40)
        Column() {
          Toggle({ type: ToggleType.Switch, isOn: this.isSwitchOn })
            .id('switch')
            .onChange((isOn: boolean) = > {
              Logger.log(`LSQ: wifi swtich is: ${isOn}`)
              AppStorage.SetOrCreate('wifiList', [])
              try {
                // 如果是打開狀態(tài),記錄狀態(tài),打開網(wǎng)絡(luò),開始掃描
                if (isOn) {
                  this.isSwitchOn = true
                  wifi.enableWifi()
                  return
                } else {
                  // 記錄狀態(tài),斷開網(wǎng)絡(luò)禁用網(wǎng)絡(luò)
                  this.isSwitchOn = false
                  this.isLinked = false
                  wifi.disconnect()
                  wifi.disableWifi()
                }
              } catch (error) {
                Logger.error(TAG, `failed,code:${JSON.stringify(error.code)},message:${JSON.stringify(error.message)}`)
              }
            })
        }
      }
      .width('100%')
      .padding({ left: 16, right: 16 })
      if (this.isLinked && this.isSwitchOn) {
        Column() {
          Text($r('app.string.connected'))
            .fontSize(22)
            .width('100%')
          Row() {
            Text(this.linkedInfo.ssid)
              .fontSize(20)
              .fontColor(Color.Black)
              .layoutWeight(1)
            Text($r('app.string.connected'))
              .fontSize(18)
              .fontColor(Color.Black)
          }
          .width('100%')
          .padding(10)
          .margin({ left: 16, right: 16 })
          .border({ radius: 15, color: Color.Gray, width: 1 })
          .backgroundColor(Color.White)
        }
        .width('100%')
        .padding({ left: 16, right: 16 })
      }
      if (this.isSwitchOn) {
        AvailableWifi({ linkedInfo: this.linkedInfo })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.index_bg'))
  }
  aboutToDisappear() {
    wifi.off('wifiConnectionChange')
    wifi.off('wifiStateChange')
  }
}
獲取wifi的詳細信息:在[About.ets]中通過WiFiModel中的getIpInfo()、getCountryCode()、getFeatureSupport()分別調(diào)用wifi.getIpInfo()、wifi.getCountryCode()、wifi.isFeatureSupported()來獲取對應(yīng)信息。 如圖中的 wifi詳情 。
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import router from '@ohos.router'
import { WifiModel } from '../model/WifiModel'
import { InfoView } from '../component/InfoView'
@Entry
@Component
struct About {
  private wifiModel: WifiModel = new WifiModel()
  build() {
    Column() {
      Row() {
        Image($r('app.media.ic_back'))
          .size({ width: 50, height: '100%' })
          .objectFit(ImageFit.Contain)
          .onClick(() = > {
            router.back()
          })
          .id('back')
        Text($r('app.string.about'))
          .fontColor(Color.White)
          .fontSize(25)
          .layoutWeight(1)
      }
      .width('100%')
      .height('8%')
      .constraintSize({ minHeight: 50 })
      .backgroundColor($r('app.color.button_color'))
      Scroll() {
        Column() {
          InfoView({ infoList: this.wifiModel.getIpInfo() })
          InfoView({ infoList: this.wifiModel.getCountryCode() })
          InfoView({ infoList: this.wifiModel.getFeatureSupport() })
        }
      }
      .layoutWeight(1)
    }
  }
}
審核編輯 黃宇
- 
                                WLAN
                                +關(guān)注
關(guān)注
2文章
665瀏覽量
75984 - 
                                鴻蒙
                                +關(guān)注
關(guān)注
60文章
2771瀏覽量
45192 - 
                                OpenHarmony
                                +關(guān)注
關(guān)注
31文章
3902瀏覽量
20576 
發(fā)布評論請先 登錄
鴻蒙實戰(zhàn)項目開發(fā):【短信服務(wù)】
36歲了還有必要轉(zhuǎn)行鴻蒙開發(fā)嗎?
鴻蒙Flutter實戰(zhàn):07混合開發(fā)
鴻蒙Flutter實戰(zhàn):08-如何調(diào)試代碼
鴻蒙Flutter實戰(zhàn):14-現(xiàn)有Flutter 項目支持鴻蒙 II
鴻蒙5開發(fā)寶藏案例分享---埋點開發(fā)實戰(zhàn)指南
【專家問答】楊光明:鴻蒙系統(tǒng)研發(fā)工程師教你從0開發(fā)鴻蒙PCB開發(fā)板
【項目實戰(zhàn)】基于RISC-V單片機的鴻蒙開發(fā)板項目
LabVIEW入門與實戰(zhàn)開發(fā)100例
華為開發(fā)者大會分論壇HarmonyOS測試技術(shù)與實戰(zhàn)-鴻蒙智聯(lián)認證生態(tài)設(shè)備測試挑戰(zhàn)
    
使用 Taro 開發(fā)鴻蒙原生應(yīng)用 —— 快速上手,鴻蒙應(yīng)用開發(fā)指南
    
          
        
        
鴻蒙實戰(zhàn)開發(fā):【W(wǎng)LAN使用】
                
 
    
           
            
            
                
            
評論