23

特定の WPA アクセス ポイントに接続する Android アプリを作成しています。接続すると、http 呼び出しが発行されます。ネットワーク構成は保存されません。wifiネットワークへの接続時のスタックオーバーフローに関するほぼすべての投稿を読みましたが、私に合った答えが見つかりません。ここに私が接続するために使用しているコードがあります..

    WifiConfiguration wc = new WifiConfiguration();
    wc.allowedAuthAlgorithms.clear();
    wc.allowedGroupCiphers.clear();
    wc.allowedPairwiseCiphers.clear();
    wc.allowedProtocols.clear();
    wc.allowedKeyManagement.clear();
    wc.SSID = "\"".concat("<ssid>").concat("\"");
    wc.preSharedKey = "\"".concat("<password>").concat("\"");
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
    wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
    wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
    wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2
    wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA
    wc.priority = 0;
    //wc.hiddenSSID = true;
    wc.status = WifiConfiguration.Status.ENABLED;
    // connect to and enable the connection
    WifiManager wifiManager = (WifiManager) getSystemService(this.WIFI_SERVICE);
    int netId = wifiManager.addNetwork(wc);
    boolean wifiEnabled = wifiManager.enableNetwork(netId, true);
    wifiManager.setWifiEnabled(true);
    Log.d("opener", "addNetwork returned " + netId);
    if (netId > 0) {
        wifiId = netId;
    }

ただし、netId は常に -1 です。2 つの異なる電話 (ICS:HTC Rezound と GingerBread:Motorola DroidX) で試しました。どちらもまったく同じ結果を示しています。私は何を間違っていますか?

編集: WPA2 アクセス ポイントで同じコードを試したところ、非常に奇妙な結果が得られました。このコードを実行すると、最初は -1 が返されますが、1 秒の遅延で同じメソッドを 2 回目に呼び出すと、有効な netId が返されます。だから質問は

  1. 上記のコードが wpa に接続しないのはなぜですか?
  2. wpa2 では、接続するために上記のメソッドを 2 回呼び出す必要があるのはなぜですか? 編集:接続するには複数回接続する必要があることがわかりました。接続に 3 ~ 4 回かかる場合があります。したがって、今のところ、構成を追加すると >0 id が返されるまでループしています。
4

5 に答える 5

16

少し遅いかもしれませんが、Open/WPA/WPA2/WEP で保護されたネットワークに接続するためにこれを試してください

    WifiConfiguration wifiConfig = new WifiConfiguration();
    wifiConfig.SSID = selectedNetwork.SSID();
    wifiConfig.status = WifiConfiguration.Status.DISABLED;
    wifiConfig.priority = 40;

    // Dependent on the security type of the selected network
    // we set the security settings for the configuration
    if (/*Open network*/) {
        // No security
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        wifiConfig.allowedAuthAlgorithms.clear();
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    } else if (/*WPA*/ || /*WPA2*/) {
        //WPA/WPA2 Security
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        wifiConfig.preSharedKey = "\"".concat(password).concat("\"");
    } else if (/*WEP*/) {
        // WEP Security
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
        wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

        if (getHexKey(password)) wifiConfig.wepKeys[0] = password;
        else wifiConfig.wepKeys[0] = "\"".concat(password).concat("\"");
        wifiConfig.wepTxKeyIndex = 0;
    }

    // Finally we add the new configuration to the managed list of networks
    int networkID = wifiMan.addNetwork(wifiConfig);

必要に応じて、さまざまなセキュリティ タイプに独自の変数を設定してください。WEP で保護されたネットワークに接続するための鍵 (しゃれを許してください) は、以下の getHexKey メソッドです。

/**
 * WEP has two kinds of password, a hex value that specifies the key or
 * a character string used to generate the real hex. This checks what kind of
 * password has been supplied. The checks correspond to WEP40, WEP104 & WEP232
 * @param s
 * @return
 */
private static boolean getHexKey(String s) {
    if (s == null) {
        return false;
    }

    int len = s.length();
    if (len != 10 && len != 26 && len != 58) {
        return false;
    }

    for (int i = 0; i < len; ++i) {
        char c = s.charAt(i);
        if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
            continue;
        }
        return false;
    }
    return true;
}
于 2013-06-01T14:30:50.773 に答える
10

共有キーが 8 文字未満の場合、-1 が返されることがわかりました。

于 2013-09-21T17:48:23.570 に答える
6

問題は、既に存在するネットワーク構成を追加しようとしていることです。電話すると:

int netId = wifiManager.addNetwork(wc);

同じ SSID のネットワーク構成が既に存在する場合、失敗します (-1 を返します)。したがって、netId が -1 であるかどうかを確認し、そうである場合は、同じ SSID を持つネットワークを検索する構成済みネットワークをトラバースし、見つかったら、networkId を返す必要があります。

コトリン:

var netId = wifiManager.addNetwork(conf)
if (netId == -1) netId = wifiManager.configuredNetworks?.let {
    it.firstOrNull { it.SSID.trim('"') == ssid.trim('"') }?.networkId ?: -1
}
wifiManager.enableNetwork(netId, true)
于 2019-08-20T07:25:40.993 に答える
5

私はちょうどこれと同じ問題を抱えていました。一見、すべてが順調だったようですが、そうではありませんでした。

私が見つけたのはこれです:

  • Android WifiStateMachine では、サプリカントが実行中で接続されていない限り、ネットワークを追加または変更することはできません。これは、起動時に実行されるサービスと、WIFI がオフの場合でも実行されるサービスに影響します。

  • Android WifiConfigStore は、Wi-Fi ネットワークの所有者を UID で追跡します。これは、別のプロセスによって作成されたネットワークを変更できない可能性があることを意味します。

ネットワークを追加する適切な方法は次のとおりです。

  1. WIFI ネットワークが有効になっているかどうかを確認します。そうでない場合は、 に電話してWifiManager.setWifiEnabled(true)ください。
  2. WifiManager.pingSupplicant()true が返されるまで待ちます。
  3. 新しい を作成して入力しWifiConfiguration、 に渡しWifiManager.addNetwork()ます。返される値が (-1) でないことを確認してください。
  4. (オプション) によって返された値addNetwork()を呼び出しの引数として使用しWifiConfiguration.enableNetwork()ます (-1 でない限り)。他のすべてのネットワークを変更する権利がない限り、ブール値パラメーターは false を意味し、 falsedisableOthersにする必要があることに注意してください。 trueに設定すると、内部的に失敗する可能性があります。

これにより、新しい Wifi ネットワークにプログラムで追加 (および接続) できるようになります。

于 2016-11-08T22:52:01.133 に答える