前言
上篇文章介绍了WiFi列表的获取与展示和WiFi状态改变的广播监听,本篇将介绍介绍对WiFi的操作,连接、忘记,查看已连接的WiFi信息等。
相关文章
1、【 Android11 WiFi开发 一 】WiFi列表获取与展示
说明
老规矩,先把WiFi连接和断开的流程梳理下。
①、点击WiFi条目,判断WiFi是否保存,如果未保存则进行Step②,否则进行Step③
②、判断WiFi是否有密码,如果有密码则弹出密码输入框,进行Step⑥,若无密码,进行Step⑦
③、WiFi是已保存状态,则弹出"忘记"、“连接” WiFi弹窗,点击"忘记"进行Step④、"连接"进行Step⑤
④、调用forgetWifi
、刷新列表
⑤、当前是否有已连接的WiFi或正在连接的WiFi,有的话忘记此WiFi,然后连接到指定的WiFi
⑥、输入密码,校验密码是否正确,如果正确,连接成功。反之,则提示密码错误
⑦、连接无密码WiFi,创建配置直接连接
实现
上述介绍了WiFi的连接和忘记流程,下面将介绍相关的API
和功能实现,当然WifiManager
还是核心类,WiFi配置类WifiConfiguration
。
1、判断WiFi是否保存过
获取连接过的WiFi配置集合,判断SSID和当前的是否一致,如果一致,说明WiFi被保存过。
/**
* 判断WiFi是否保存过
*/
fun isWiFiSaved(ssid:String):WifiConfiguration?{
val configs = wifiManager.configuredNetworks
configs.forEach { if(it.SSID.equals("\"" + ssid + "\"")){ return it } }
return null
}
2、忘记WiFi
当前WiFi被保存过,可以执行"忘记"WiFi,首先要去获取此WiFi的配置,这个配置是在连接WiFi时候创建的。
/**
* 获取当前SSID的WiFi配置
* @param[ssid] 字符串或一串16进制的数字
*/
fun getWiFiConfig(ssid: String?): WifiConfiguration? {
val configs = wifiManager.configuredNetworks
if(App.DEBUG) Log.i(TAG,"configs size = ${configs.size}")
if (configs != null && configs.size > 0 ) {
for( config in configs){
if(App.DEBUG) Log.i(TAG,"config = $config")
val configSSID = config.SSID.replace("\"", "")
if (ssid == configSSID) return config
}
}
return null
}
忘记WiFi,首先要获取到该网络的networkId
,根据networkId
禁用和删除该网络,再断开网络的连接。
/**
* 忘记连接过WiFi
* @param[config] 指定WiFi的配置
*/
fun forgetWiFi(config: WifiConfiguration?):Boolean {
var success = false
if(config?.isPasspoint == true){
wifiManager.removePasspointConfiguration(config.FQDN)
success = true
}else{
config?.networkId?.let {
wifiManager.disableNetwork(it)
wifiManager.removeNetwork(it)
wifiManager.disconnect()
success = true
}
}
return success
}
3、连接已保存的WiFi
通过SSID获取WiFi配置,获取到networkId后使能网络,保存下当前配置。
/**
* 连接到保存过的WiFi
* @param[ssid] 字符串或一串16进制的数字
*/
fun connectSavedWiFi(ssid:String){
if(App.DEBUG) Log.i(TAG,"ssid = $ssid")
val config = getWiFiConfig(ssid)
config?.networkId?.let { enableNetwork(it,true) }
wifiManager.saveConfiguration()
}
/**
* 使能网络
*/
fun enableNetwork(networkId: Int, b: Boolean): Boolean {
return wifiManager.enableNetwork(networkId, b)
}
介绍完对已保存的WiFi的操作,下面将对新的WiFi连接做介绍。
4、判断WiFi是否有密码
enum class WiFiSecurity(security :String){
NONE("Nothing"),
WEP("WEP"),
PSK("WPA/WPA2 PSK"),
EAP("802.1x EAP"),
OWE("OWE"),
SAE("SAE");
fun getSecurity(result: ScanResult):WiFiSecurity {
if (result.capabilities.contains("WEP")) {
return WEP
} else if (result.capabilities.contains("PSK")) {
return PSK
} else if (result.capabilities.contains("EAP")) {
return EAP
} else if (result.capabilities.contains("OWE")) {
return OWE
} else if (result.capabilities.contains("SAE")) {
return SAE
}
return NONE
}
}
5、连接有密码的WiFi
val networkId = WiFiUtils.createWiFiConfig(wifiList,result.SSID,password)
WiFiUtils.enableNetwork(networkId,true)
/**
* 创建WiFi配置
*/
fun createWiFiConfig(wifiList:ArrayList<ScanResult>,ssid:String,pwd:String):Int{
var networkId = -1
wifiList.forEach {
if(it.SSID.equals(ssid)){
val config = WifiConfiguration().apply {
SSID = "\"" + it.SSID + "\""
preSharedKey = "\"" + pwd + "\""
hiddenSSID = false
status = WifiConfiguration.Status.ENABLED
}
networkId = wifiManager.addNetwork(config)
}
}
return networkId
}
5、连接无密码的WiFi
val networkId = WiFiUtils.createNoPwConfig(result.SSID),true)
WiFiUtils.enableNetwork(networkId,true)
/**
* 创建无密码WiFi配置
*/
fun createNoPwConfig(ssid:String):Int{
val config = WifiConfiguration().apply {
allowedAuthAlgorithms.clear()
allowedGroupCiphers.clear()
allowedKeyManagement.clear()
allowedPairwiseCiphers.clear()
allowedProtocols.clear()
SSID = "\"" + ssid + "\""
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
}
return wifiManager.addNetwork(config)
}
连接WiFi,系统会返回连接的结果,是否连接成功、密码是否正确等,Android中也是提供了对应的广播WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
/**
* 获取WiFi连接过程的状态
*/
fun getState():SupplicantState{
val info = wifiManager.connectionInfo
return info.supplicantState
}
/**
* WiFi连接过程处理
* @param[state] 请求状态
*/
private fun connectProcess(intent:Intent,state: SupplicantState) {
when(state){
SupplicantState.SCANNING ->{ if(App.DEBUG) Log.i(TAG,"WiFi正在扫描") }
SupplicantState.ASSOCIATING -> { if(App.DEBUG) Log.i(TAG,"正在关联AP") }
SupplicantState.AUTHENTICATING -> { if(App.DEBUG) Log.i(TAG,"正在验证") }
SupplicantState.ASSOCIATED -> { if(App.DEBUG) Log.i(TAG,"关联AP成功") }
SupplicantState.COMPLETED ->{
if(App.DEBUG) Log.i(TAG,"连接成功")
}
SupplicantState.DORMANT,
SupplicantState.DISCONNECTED ->{
if(App.DEBUG) Log.i(TAG,"连接不成功")
}
else ->{ if(App.DEBUG) Log.i(TAG,"其他情况") }
}
//获取错误结果
val connectResult = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR,123)
if(App.DEBUG){ Log.i(TAG,"WiFi Link Error: $connectResult") }
if(connectResult == WifiManager.ERROR_AUTHENTICATING){
if(App.DEBUG) Log.i(TAG,"密码错误")
ctx.toast(R.string.pw_incorrect_retry)
}
}
结尾
这是Android11
上WiFi开发记录的第二篇文章,连接已保存的WiFi、忘记已保存的WiFi、连接有密码和无密码的WiFi。后续篇幅将介绍WiFi信息的获取、WiFi设置静态IP地址等功能。