Android系統的移動設備大多支持無線WLAN技術。利用該技術,不僅能實現互聯網通信,還能實現無線定位,熱點共享等遠程通信功能。針對使用WLAN的不同功能,可能需要分別申請不同的權限聲明,同時調用不同的系統框架API,下文將按照不同的使用功能分別介紹。
掃描無線設備
該功能通常只允許在系統自帶的設置應用中使用,當然如果是第三方應用的目標版本在Android 9.0即API 28以下,也可以使用該功能。掃描周圍的無線設備,需要用到android.net.wifi.WifiManager wifi管理類。
權限聲明
在掃描無線設備時,需要啟用設備的位置開關,同時申請Manifest.permission.ACCESS_FINE_LOCATION="android.permission.ACCESS_FINE_LOCATION"
精確定位權限或者Manifest.permission.ACCESS_COARSE_LOCATION="android.permission.ACCESS_COARSE_LOCATION"
模糊定位權限。
另外,由於需要使用設備的WLAN才能掃描,所以需要申請獲取設備自身wifi狀態的權限Manifest.permission.ACCESS_WIFI_STATE="android.permission.ACCESS_WIFI_STATE"
。
同樣掃描也會修改設備自身的wifi狀態,所以也需要聲明wifi狀態修改的權限Manifest.permission.CHANGE_WIFI_STATE="android.permission.CHANGE_WIFI_STATE"
。
掃描流程
首先在可以獲取上下文環境Context
對象的位置,調用該對象的getSystemService(String name)
方法,參數 name 值為Context.WIFI_SERVICE="wifi"
,返回WifiManager
wifi管理類對象。
在需要開啟掃描的位置,調用WifiManager
對象的startScan()
方法,即可開始掃描,該方法會返回boolean
類型的結果標志是否成功啟動掃描。
雖然已經成功啟動了掃描無線設備的功能,但是查看掃描結果還需要借助四大組件中負責進程間通信的廣播接收器。自定義BroadcastReceiver
的目的就是用於接收掃描結果。因此在調用context.registerReceiver(BroadcastReceiver receiver, IntentFilter intentFilter)
方法注冊該廣播接收器時,通過IntentFilter
對象設置的意圖行為addAction(String action)
傳入的參數 action 值為WifiManager.SCAN_RESULTS_AVAILABLE_ACTION="android.net.wifi.SCAN_RESULTS"
。最終,在該類的onReceiver(Context context, Intent intent)
方法中,可以對接收到的參數 intent 意圖獲取保存的結果,調用該參數的getBooleanExtra(String key, boolean default)
方法,傳入參數 key 的值為WifiManager.EXTRA_RESULTS_UPDATED="resultsUpdated"
,即可得到boolean
類型的實際掃描結果。
在得到掃描結果為true
之后,可以繼續調用WifiManager
對象的getScanResults()
方法獲取掃描結果,得到由android.net.wifi.ScanResult掃描結果類組成的List
數組。
建立網絡連接
通過WLAN設備可以建立網絡連接,以此與其他WLAN設備通信。建立wifi連接的途徑主要有兩種,包括連接其他WLAN廣播設備,或者與另外一個WLAN設備建立一對一連接(俗稱熱點連接)。之后的連接狀態和通信過程,則都是主要借助android.net.ConnectivityManager連接管理類。獲取該連接管理類對象的方法同樣是在可以獲取上下文環境Context
對象的位置,調用該對象的getSystemService(String name)
方法,參數 name 值為Context.CONNECTIVITY_SERVICE="connectivity"
,返回ConnectivityManager
連接管理類對象。其后流程暫先不表,這里主要介紹如何建立wifi連接。
權限聲明
與其他WLAN設備建立網絡連接,首先要在清單文件中聲明獲取wifi狀態權限Manifest.permission.ACCESS_WIFI_STATE。
WLAN廣播連接
在Android 10即API 29版本以前,主要依賴WifiManager
管理類對象。而從Android10及API 29版本開始,改由android.net.wifi.WifiNetworkSuggestionwifi網絡建議類執行相關操作。
適用於API 29之前版本
通過android.net.wifi.WifiConfiguration的相關變量,配置要連接的WLAN設備信息,包括 SSID 對應的wifi名, preSharedKey對應的wifi密碼, allowKeyManagement 對應的加密方式等信息。
在創建並配置WifiConfiguration
對象的相關信息之后,調用WifiManager
對象的addNetwork(WifiConfiguration config)
方法,將上述對象作為參數 config 的值傳入,即可得到 int
類型的本地id索引值,如果添加失敗,則返回的該索引值將為非正數。成功得到該索引值之后,再次調用WifiManager
對象的enableNetwork(int netId, boolean attemptConnect)
,其參數 netId 即得到的索引值傳入,參數 attemptConnect 如果為true
會立即嘗試連接,否則只是保存該wifi信息,並不會自動連接。
一旦系統嘗試連接,網絡連接狀態會通過系統廣播實時發送,因此如果想在應用程序中實時監聽網絡連接狀態,只需要在獲取上下文環境Context
對象的位置,注冊一個自定義的BroadcastReceiver
廣播接收器。監聽的Intent
意圖對象中的 action 參數值WifiManager.RSSI_CHANGED_ACTION="android.net.wifi.RSSI_CHANGED"
為連接的WLAN設備RSSI發生改變時的行為標簽。另外可以通過意圖對象的getBundle()
等系列參數獲取網絡狀態信息,其值均在WifiManager
中以常量形式定義。
適用於API 29及以后版本
通過android.net.wifi.WifiNetworkSuggestion.Builder建造者模式的無參構造方法和setX()
系列方法配置要連接的WLAN設備信息,包括setSsid(String ssid)
對應的wifi名,和setWpa2Passphrase(String passphrase)
對應設置wpa2加密模式下的密碼,及其他相關參數。最終調用該對象的build()
方法,返回建造出來的WifiNetworkSuggestion
wifi網絡建議類的實例化對象。可以同時創建多個不同的WifiNetworkSuggestion
對象,以List
列表的形式保存。
之后調用WifiManager
管理類對象的addNetworkSuggestions(List<WifiNetworkSuggestion> networkSuggestions)
方法,參數 networkSUggestions 便是所有要保存的WifiNetworkSuggestion
對象集合。返回int
類型的結果標記添加操作是否執行成功,如果執行成功,將會返回WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS=0
的標記值。
在網絡添加成功后,同樣可以通過注冊自定義的BroadcastReceiver
的方式監聽網絡連接狀態。與API 29以前的版本不同的是,這里要監聽的Intent
意圖對象中的參數 action 行為值為WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION="android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION"
,在該行為值下同樣可以獲取網絡狀態信息。