2014-03-13 47 views
0

在我的應用程序中,我有一個網絡選擇屏幕,顯示所有可見網絡 - 包括已配置隱藏SSID。Android - WiFi Association禁用隱藏WiFi配置

但是,當用戶選擇不是隱藏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所示的網絡中,布爾值)

mWifiManager.enableNetwork(id, true); 

禁止所有其它配置。這對於非隱藏的SSID是可以的,但這意味着我的隱藏SSID配置被禁用,並且不再包含在掃描結果中。這意味着如果用戶在隱藏網絡上並加入另一個網絡,則除非他們啓動他們的設備Wifi設置,否則他們不能回去加入他們的隱藏網絡。

我發現以編程方式更改Wifi網絡的上述方法必須與設備Wifi設置使用的方法不同。如果您以編程方式關聯,則進入Wifi Settings屏幕,您將看到所有其他Configured Networks已被設置爲「Disabled」。但是,如果您從設備Wifi設置屏幕關聯到網絡,則所有其他Wifi配置保持「保存」狀態。

有沒有人有一種替代的方法,以編程方式關聯到保留隱藏SSID配置的網絡而不禁用它們?

謝謝,這是一個真正的痛苦。

回答

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是一個簡單的類,它可以讓我暫時保留一些額外的信息,很容易accessable。這裏是解釋什麼_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 { 
    } 
} 

希望這對於其他人來說會派上用場。