Android - WiFi协会禁用隐藏的WiFi配置

时间:2014-03-13 09:32:33

标签: android networking hidden ssid

在我的应用程序中,我有一个网络选择屏幕,它显示所有可见的网络 - 包括已配置的隐藏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配置而不禁用它们的网络?

谢谢,这是一个真正的痛苦。

1 个答案:

答案 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 {
    }
}

希望这对其他人来说会派上用场。