好的,我现在似乎已经修复了它。
这是我修改后的关联逻辑 - 我实际上已将其拆分为单独的方法,但为了便于阅读,我将在一个方法中将其全部发布。
简单地说,我在执行关联之前找到所有可见的隐藏网络,敏锐地参考这些,然后关联到用户选择的网络,然后重新启用隐藏的 SSID 配置而不禁用任何其他配置。
public boolean associate(ScanResultWrapper scanResult){
WifiConfiguration wc = getWifiConfiguration(scanResult._scanResult);
int id = -1;
if (wc == null ) {
wc = new WifiConfiguration();
wc.SSID = "\"" + scanResult._Ssid + "\"";
wc.BSSID = scanResult._scanResult.BSSID;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
id = mWifiManager.addNetwork(wc);
if (!mWifiManager.saveConfiguration()){
return false;
}
} else{
id = wc.networkId;
}
boolean result;
//Get reference to all hidden visible networks
ArrayList<ScanResultWrapper> hiddenScanResults = new ArrayList<ScanResultWrapper>();
for (ScanResultWrapper wrapper : mScanResults){
if (wrapper._isHidden){
hiddenScanResults.add(wrapper);
}
}
try {
//Enable the user network - disabling all others
result = mWifiManager.enableNetwork(id, true);
//re-enable all hidden networks, leaving all other networks enabled
for (ScanResultWrapper wrapper : hiddenScanResults){
WifiConfiguration wcHidden = getWifiConfiguration(wrapper._scanResult);
//the false is the important part here
mWifiManager.enableNetwork(wcHidden.networkId, false);
}
return result;
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
ScanResultsWrapper 类是一个简单的类,它允许我保留一些额外的信息并且可以轻松访问。这是解释 _isHidden 变量设置的构造函数。
public ScanResultWrapper(ScanResult scanResult, Context c) {
this._Ssid = scanResult.SSID;
this._scanResult = scanResult;
this.context = c;
WifiManager mWifiManager = (WifiManager) c.getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
WifiConfiguration config = getWifiConfiguration(scanResult, configs) ;
this._isKnown = config != null;
if (config!=null){
_isHidden = config.hiddenSSID;
}else{
_isHidden = false;
}
this._isAssociated = _Ssid.equals(SSIDUtils.checkSSIDForEnclosingQuotes(mWifiManager.getConnectionInfo().getSSID()));
if (_isAssociated){
this._isAssociated = mWifiManager.getConnectionInfo().getNetworkId()!= -1 ? true : false;
}
this._isSecure = scanResult.capabilities.contains("WEP") || scanResult.capabilities.contains("PSK") || scanResult.capabilities.contains("EAP");
}
/**
* returns the wifi configuration for a given ScanResult. It compares the ssid AND the bssid
* @param ssid
* @param configs
* @return
*/
public WifiConfiguration getWifiConfiguration(ScanResult scanResult, List<WifiConfiguration> configs) { // ScanResult result) {
try {
String ssid = scanResult.SSID;
ssid = ssid.replaceAll("\"", "");
ssid = ssid.trim();
String bssid = scanResult.BSSID;
if ( bssid != null ) {
bssid = bssid.replaceAll("\"", "");
bssid = bssid.trim();
}
if (configs== null){
return null;
}
for ( WifiConfiguration config : configs ) {
String candidate = config.SSID;
if ( BSGStringUtils.isNullOrEmpty(candidate) ) {
continue;
}
candidate = candidate.replaceAll("\"", "");
candidate = candidate.trim();
if ( candidate.equals(ssid) ) {
String candidateBSSID = config.BSSID;
if ( candidateBSSID == null && bssid == null ) {
return config;
}else if (candidateBSSID == null){
return config;
} else if ( candidateBSSID != null && bssid != null && candidateBSSID.equals(bssid) ) {
return config;
} else {
}
} else {
}
}
return null;
} finally {
}
}
希望这对其他人有用。