在我的应用程序中,我有一个网络选择屏幕,它显示所有可见的网络 - 包括已配置的隐藏SSID。
但是,当用户选择不是隐藏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;
try {
result = mWifiManager.enableNetwork(id, true);
return result;
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
所以关联到这里显示的网络的方法http://developer.android.com/reference/android/net/wifi/WifiManager.html#enableNetwork(int,boolean)
mWifiManager.enableNetwork(id, true);
禁用所有其他配置。这对于非隐藏的SSID是可以的,但这意味着我的隐藏SSID配置被禁用,并且不再包含在扫描结果中。这意味着如果用户在隐藏网络上并加入另一个网络,除非他们启动设备Wifi设置,否则他们无法返回加入他们的隐藏网络。
我发现上述以编程方式更改Wifi网络的方法必须与设备Wifi设置使用的方法不同。如果您以编程方式关联然后转到Wifi设置屏幕,您将看到所有其他已配置的网络已设置为"已禁用"。但是,如果您从设备Wifi设置屏幕关联到网络,则所有其他Wifi配置保持为"已保存"。
是否有人有另一种方法可以编程方式关联到保留隐藏SSID配置而不禁用它们的网络?
谢谢,这是一个真正的痛苦。
答案 0 :(得分:0)
好吧,我好像现在已经修好了。
这是我修改后的相关逻辑 - 我实际上将其拆分为单独的方法,但为了便于阅读,我将在一个方法中将其全部发布。
简单地说,我发现在执行关联之前可见的所有隐藏网络,对这些网络的敏锐引用,然后关联到用户选择的网络,然后重新启用隐藏的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 {
}
}
希望这对其他人来说会派上用场。