安卓WifiManager.addNetwork()返回-1(Android WifiManager

2019-06-27 03:31发布

我写一个Android应用程序将连接到特定的WPA接入点连接时,它会发出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。 我已经尝试过了两个不同的手机(ICS:HTC Rezound和姜饼:摩托罗拉DroidX)。 无论准确显示同样的结果。 我究竟做错了什么?

编辑:我试着用WPA2接入点相同的代码,并得到了非常奇怪的结果。 当被运行这段代码,它第一次将返回-1,但如果我叫同样的方法第二次用1秒的延迟,它会返回有效的NetID。 所以,问题是

  1. 为什么上面的代码无法连接到WPA?
  2. 在WPA2,为什么我需要上面的方法调用两次来进行连接? 编辑:我认为,我必须连接来进行连接多次。 有时候,它会采取3-4次进行连接。 所以现在我循环,直到将配置返回> 0的ID。

Answer 1:

可能有点晚了,但这个尝试连接到打开/ 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;
}


Answer 2:

我发现,如果共享密钥为少于8个字符,则返回-1。



Answer 3:

我有同样的问题。 我发现你的无线网络必须是当你在呼唤addNetwork。



Answer 4:

我只是有这个同样的问题。 看似一切正常,但随后 - 事实并非如此。

我发现是这样的:

  • Android的WifiStateMachine不会允许您添加或修改网络,除非请求方运行,并连接到。 这会影响启动和运行,即使是WIFI关闭服务运行的服务。

  • Android的WifiConfigStore通过UID跟踪wifi网络的拥有者。 这意味着你可能无法修改由另一个进程创建的网络。

添加网络的正确方法是:

  1. 检查WIFI网络已启用。 如果没有,请致电WifiManager.setWifiEnabled(true)
  2. 等到WifiManager.pingSupplicant()返回true。
  3. 创建并填写新的WifiConfiguration ,然后将它传递给WifiManager.addNetwork() 确保返回的值是不是(-1)。
  4. (可选)使用由返回值addNetwork()作为参数传递给WifiConfiguration.enableNetwork()调用(除非它是-1)。 请注意,布尔参数表示disableOthers ,应该是假的 ,除非你有权限修改所有其他网络:它可以在内部失败,如果你把它设置为true。

这应该允许您以编程方式添加(并连接)到一个新的WiFi网络。



文章来源: Android WifiManager.addNetwork() returns -1