Android 如何判斷 Wi-Fi 是 2.4G+5G 雙頻?

前言

由於穩定性、成本等原因,大部分智能家居設備都只支持連接 2.4G 的無線網絡。所以我們在利用 APP 實現配網的時候就需要判斷 Wi-Fi 是 2.4G、5G,還是 2.4G+5G 雙頻,也就是大部分智能家居設備是無法連接純 5G Wi-Fi 的,如果用戶手機連接的是純 5G Wi-Fi 就需要給用戶一個提示信息,2.4G+5G 雙頻則不需要提示。

很多人肯定會想 “這個有什麼難的?” 掃描出的 Wi-Fi 結果中肯定有屬性可以判斷。其實並沒有這麼簡單,我們的測試人員在禪道上提了這個問題,結果我們團隊負責這個功能的 Android 和 IOS 兩位小夥伴就把這個 bug 在禪道上晾了幾個月,他們說確實沒什麼辦法可以直接判斷。

我今天沒這麼忙就想起了這個問題,就想着看看能不能把這個問題解決掉。經過查詢資料,確實可以通過掃描的頻率(frequency)來判斷是 2.4G 還是 5G,但是無法判斷出是 2.4G+5G 雙頻。我就不信了,Google 一頓搜索,發現還真沒有解決方案!

經過一個下午的分析後面終於解決了!發現這個問題其實並不難,只是我一開始和其他兩個小夥伴一樣,由於對 Wi-Fi 頻段不熟悉,思維沒有轉變過來,總是想着通過某個 Wi-Fi 返回的信息來判斷是不是 2.4G+5G 雙頻,這個是行不通的,後面慢慢分析爲什麼行不通。

一、頻段

我們在淘寶上買路由器的時候,經常會搜索到標題包含 雙頻 的路由器,這裏的雙頻指的是這個路由器可以開兩個頻段的網絡,分別是 2.4GHz 頻段和 5GHz 頻段。具體區別如下:

  • 2.4GHz 頻段
    2.4GHz 頻段的網絡接入速率爲 72M,Wi-Fi 協議對應的是 802.11n。特點是速率低,信道少干擾大,穿牆能力強,覆蓋距離遠。頻率在 2400 到 2500 之間,不包含頭尾。
  • 5GHz 頻段
    5GHz 頻段的網絡接入速率是 433M,Wi-Fi 協議對應的是 802.11ac。特點是速率高,信道多幹擾小,穿牆能力差,覆蓋距離也比較近。頻率在 4900 到 5900 之間,不包含頭尾。

如果路由器開啓了雙頻合一功能,那麼這個路由器就會同時發出 2.4GHz 頻段和 5GHz 頻段的網絡,但是它們在手機上顯示的確是同一個 SSID(Wi-Fi 名稱),我們連接的時候可能連接的是 2.4GHz 頻段,也可能是 5GHz 頻段,連接哪個取決於當時的環境、網絡狀況等原因。

二、代碼分析

看到我上面標註的重點了嗎?突破口就是這裏!雙頻路由器會 同時 發出兩個頻段的網絡,但是卻顯示 同一個 SSID(Wi-Fi 名稱)。如果這個時候我們路由器設置的 Wi-Fi 名稱是 “wildma_wifi”,那麼我們手機上就只顯示一個該名字的 Wi-Fi,而不會顯示兩個同名的。

然後我們連接的時候,利用代碼打印出來,也是隻有一個頻率。如下:

val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiInfo = mWifiManager.connectionInfo
val frequency = wifiInfo.frequency

得到的 frequency 要麼在 2400 到 2500 之間,要麼就在 4900 到 5900 之間。這樣就只能判斷 Wi-Fi 是 2.4G 還是 5G,而無法判斷出是 2.4G+5G 雙頻。

所以如果你不瞭解雙頻,那麼思維就會一直停留在這裏,無法得到答案。我們瞭解雙頻後,知道雙頻路由器會 同時 發出兩個頻段的網絡,那麼我們就可以遍歷掃描到的 Wi-Fi,如果同一個 SSID 的 Wi-Fi 出現兩次,並且頻率不一樣,那麼連接的這個 Wi-Fi 就是 2.4G+5G 雙頻。
代碼如下:

class MainActivity : AppCompatActivity() {

    var mWifiScanResults = HashMap<String, WifiScanResult?>()

    /**
     * 處理掃描結果
     *
     * @param scanResults 掃描結果集合
     */
    private fun handleScanResult(scanResults: List<ScanResult>) {
        for (i in scanResults.indices) {
            val scanResult = scanResults[i]
            val ssid = scanResult.SSID
            if (!mWifiScanResults.containsKey(ssid)) {
                mWifiScanResults[ssid] = WifiScanResult()
            }
            mWifiScanResults[ssid]?.setFrequency(scanResult.frequency)
        }
    }
}
class WifiScanResult {
    // 是否是 2.4G
    private var is24G = false

    // 是否是 5G
    private var is5G = false

    /**
     * 設置頻率
     *
     * @param frequency 頻率
     */
    fun setFrequency(frequency: Int) {
        if (frequency in 2401..2499) {
            is24G = true
        }
        if (frequency in 4901..5899) {
            is5G = true
        }
    }
}

完整源碼:Wifi

三、總結

一個問題可能並不難,但是如果你不瞭解某個知識點,思維就轉變不了,就會一直卡在某個點。

關於我

我是 wildmaCSDN 認證博客專家簡書程序員優秀作者,擅長屏幕適配
如果文章對你有幫助,點個贊就是對我最大的認可!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章