(注意:这里功能的添加并非在原生设置中)在设置中添加wpa3的Type
public enum WifiSecurity {
WEP(R.string.wifi_security_type_wep),
PSK(R.string.wifi_security_type_wpa),
EAP(R.string.wifi_security_type_eap),
SAE(R.string.wifi_security_type_sae),
NONE(R.string.wifi_security_type_none);
public static WifiSecurity getSecurity(ScanResult result) {
if (result.capabilities.contains("WEP")) {
return WEP;
} else if (result.capabilities.contains("PSK")) {
return PSK;
} else if (result.capabilities.contains("SAE")) {
return SAE;
} else if (result.capabilities.contains("EAP")) {
return EAP;
}
return NONE;
}
public static WifiSecurity getSecurity(WifiConfiguration config) {
if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
return PSK;
}
if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
|| config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return EAP;
}if(config.allowedKeyManagement.get(KeyMgmt.SAE)){
return SAE;
}
return (config.wepKeys[0] != null) ? WEP : NONE;
}
在这三个类中分别添加wpa3的Type,也就是SAE的类型判断,接下来点击连接时会执行以下方法:
private void performConnect() {
isPerformConnect = true;
//加入网络
setViewsEnable(false);
if (isEthernetConnected()) {
notifyStatusViews(RESULT_ETHERNET_CONNECTED);
return;
}
String password = null;
String ssid = null;
ssid = mScanResult.SSID;
String strIdentity = null;
WifiConfigHelper.setConfigSsid(mConfiguration, ssid);
WifiConfigHelper.setConfigKeyManagementBySecurity(mConfiguration, mWifiSecurity);
if (mWifiSecurity == WifiSecurity.NONE || isWifiSaved) {
//optionsOrConnect();
} else if (mWifiSecurity == WifiSecurity.EAP) {
strIdentity = editTextIdentity.getText().toString();
password = editTextPassword.getText().toString();
WifiConfigHelper.setIdentityConfig(mConfiguration, strIdentity);
WifiConfigHelper.setIdentityPassword(mConfiguration, password);
} else {
password = editTextPassword.getText().toString();
setWifiConfigurationPassword(mConfiguration, mWifiSecurity, password);
}
//WifiConfigHelper.saveConfiguration(this, mConfiguration);
mWifiManager.connect(mConfiguration, this);
mHandler.sendEmptyMessage(MSG_STARTING_CONNECT);
Log.d(TAG, "ssid:" + ssid + "password:" + password + "mWifiSecurity:" + mWifiSecurity.toString());
}
注意到安全类型为PSK、SAE都会进入else语句中,那么再来看看setWifiConfigurationPassword(mConfiguration, mWifiSecurity, password)方法:
protected void setWifiConfigurationPassword(
WifiConfiguration wifiConfiguration, WifiSecurity wifiSecurity, String password) {
if (wifiSecurity == WifiSecurity.WEP) {
int length = password.length();
// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
if ((length == 10 || length == 26 || length == 58)
&& password.matches("[0-9A-Fa-f]*")) {
wifiConfiguration.wepKeys[0] = password;
} else {
wifiConfiguration.wepKeys[0] = '"' + password + '"';
}
} else {
if (WifiSecurity.SAE.equals(wifiSecurity)){//当无线网络中连接路由器设置WPA3类型的WiFi时,需要指定wifiConfiguration的安全参数,否则无法连接
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
}
}
wifiConfiguration.preSharedKey = '"' + password + '"';
}
}
这里又会进wifiSecurity的判断,在类型判断的else语句中加入有关SAE类型的判断, wifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);z这行代码极为重要,缺少就会导致连接不上wpa3的wifi,实际上是当进行wifi连接时,首先通过WifiSecurity中的
getSecurity(WifiConfiguration config)方法获取到所要连接的Wifi类型,再在setWifiConfigurationPassword方法里面针对SAE类型的wifi设置wifiConfiguration的安全参数为SAE,如此一来就能实现连接