首先要獲取 WifiManager
,後面的所有操作基本上都要用到。
val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
打開關閉WIFI
打開或者關閉WIFI直接調用 WifiManager.isWifiEnabled = true / false
就可以了,但是要監聽操作結果的話,有兩種方法,一個是監聽廣播,一個是寫循環主動查詢,我個人覺得還是主動查詢可靠點,下面是我封裝的方法:
/**
* 異步打開、關閉wifi,並回調。10秒超時。
* @param enabled 打開/關閉 WIFI。
* @param callback 結果回調,success:打開/關閉成功。UI線程回調。
*/
private fun WifiManager.enable(enabled: Boolean, callback: (success: Boolean) -> Unit) {
GlobalScope.launch(Dispatchers.IO) {
// 當前狀態一致,直接回調
if (isWifiEnabled == enabled) {
GlobalScope.launch(Dispatchers.Main) { callback.invoke(true) }
return@launch
}
isWifiEnabled = enabled
repeat(10) {
delay(1000)
// 當前狀態一致,直接回調
if (isWifiEnabled == enabled) {
GlobalScope.launch(Dispatchers.Main) { callback.invoke(true) }
return@launch
}
}
GlobalScope.launch(Dispatchers.Main) { callback.invoke(false) }
}
}
// 這樣調用即可
wifiManager.enable(isChecked) { success ->
// 直接用 wifiManager.isWifiEnabled 判斷更可靠點
if (wifiManager.isWifiEnabled) {
// WIFI 已打開
} else {
// WIFI 已關閉
}
}
掃描WIFI
掃描結果通過 wifiManager.scanResults
獲取,但是獲取到的可能是以前的掃描結果,所以我們要等收到廣播後再獲取結果。
// 廣播接收器
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
wifiManager.scanResults.filter {
!TextUtils.isEmpty(it.SSID)
}.forEach {scanResult->
LogUtils.d(TAG, scanResult)
// 展示列表
}
}
}
}
// 註冊廣播
registerReceiver(receiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
// 掃描
wifiManager.startScan()
// 註銷廣播
unregisterReceiver(receiver)
連接WIFI
連接WIFI要調用好幾個接口,首先要根據帳號密碼生成WifiConfiguration
,然後addNetwork(config)
,返回-1表示失敗,addNetwork只是把配置添加到配置列表,還需要調用 enableNetwork(networkId, true)
纔是真正的連接WIFI,最後調用saveConfiguration
保存一下。操作結果依然是通過廣播接收。
1、生成WifiConfiguration
比較複雜,這裏寫了個獨立的方法,代碼是網上的稍作修改了。
// 獲取已經存在的SSID對應的配置
private fun WifiManager.getConfiguredNetwork(ssid: String): WifiConfiguration? {
configuredNetworks.forEach {
if (it.SSID == "\"$ssid\"") return it
}
return null
}
private fun WifiManager.createWifiConfiguration(ssid: String, password: String, scanResult: ScanResult? = null): WifiConfiguration {
// 判斷是否已經存在
val config = getConfiguredNetwork(ssid)
if (config != null) {
LogUtils.d(TAG, "已經存在 $ssid 執行移除操作")
val successful = removeNetwork(config.networkId)
LogUtils.d(TAG, "移除操作 ${if (successful) "成功" else "失敗"}")
}
val capabilities = scanResult?.capabilities ?: "wpa"
return WifiConfiguration().apply {
allowedAuthAlgorithms.clear()
allowedGroupCiphers.clear()
allowedKeyManagement.clear()
allowedPairwiseCiphers.clear()
allowedProtocols.clear()
SSID = "\"" + ssid + "\""
when {
capabilities.contains("wep", ignoreCase = true) -> {
hiddenSSID = true
wepKeys[0] = "\"" + password + "\""
allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
wepTxKeyIndex = 0
}
capabilities.contains("psk", ignoreCase = true) -> {
preSharedKey = "\"" + password + "\""
hiddenSSID = true
allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
status = WifiConfiguration.Status.ENABLED
}
else -> {
// 沒有密碼
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
}
}
}
}
2、連接
// 這裏增加個變量多重判斷一下
private var enableNetworkSuccessful = false
private fun connect() {
val ssid = et_name.text.toString()
val password = et_password.text.toString()
val config = wifiManager.createWifiConfiguration(ssid, password, wifiWrapper?.wifi)
LogUtils.d(TAG, "創建 WifiConfiguration:$config")
val networkId = wifiManager.addNetwork(config)
LogUtils.d(TAG, "addNetwork 返回:$networkId")
enableNetworkSuccessful = wifiManager.enableNetwork(networkId, true)
LogUtils.d(TAG, "enableNetwork 返回:$enableNetworkSuccessful")
if (enableNetworkSuccessful) {
val successful = wifiManager.saveConfiguration()
LogUtils.d(TAG, "saveConfiguration 返回:$successful")
}
}
3、監聽結果
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
WifiManager.SUPPLICANT_STATE_CHANGED_ACTION -> {
LogUtils.i(TAG, "收到廣播:SUPPLICANT_STATE_CHANGED_ACTION")
val error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 123)
if (WifiManager.ERROR_AUTHENTICATING == error) {
LogUtils.e(TAG, "密碼錯誤")
ToastUtils.show("密碼錯誤")
progressDialog.dismiss()
}
}
WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
LogUtils.i(TAG, "收到廣播:NETWORK_STATE_CHANGED_ACTION")
try {
val info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO) as? NetworkInfo
LogUtils.i(TAG, "EXTRA_NETWORK_INFO=$info")
when (info?.state) {
NetworkInfo.State.CONNECTING -> ToastUtils.show("正在連接...")
NetworkInfo.State.CONNECTED -> {
// 連接成功
if (enableNetworkSuccessful) {
LogUtils.i(TAG, "CONNECTED")
ToastUtils.show("連接成功")
successful = true
progressDialog.dismiss()
dismiss()
}
}
else -> Unit
}
} catch (e: Exception) {
LogUtils.printStackTrace(e)
}
}
}
}
}
// 註冊廣播
registerReceiver(receiver, IntentFilter().apply {
addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
})
// 註銷廣播
unregisterReceiver(receiver)