0

私のアプリには、ネットワーク選択画面があります。これには、構成された非表示の 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 構成を無効にせずに保持するネットワークにプログラムで関連付ける代替方法はありますか?

ありがとう、これは本当の痛みです。

4

1 に答える 1

0

さて、私は今それを修正したようです。

これが私の改訂されたアソシエイト ロジックです。実際にはこれを別々のメソッドに分割しましたが、ここでは読みやすくするために、すべてを 1 つのメソッドにまとめて投稿します。

簡単に言えば、関連付けを実行する前に表示されているすべての非表示のネットワークを見つけて、これらを鋭く参照し、ユーザーが選択したネットワークに関連付けてから、非表示の 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 {
    }
}

うまくいけば、これは他の誰かにとって便利になるでしょう。

于 2014-03-14T10:28:27.600 に答える