Android WifiManager.addNetwork() returns -1

后端 未结 5 488
深忆病人
深忆病人 2020-12-10 10:47

I am writing an android app which will connect to a specific WPA access point, when connected, it will issue a http call. It will not save the network config. I have read al

相关标签:
5条回答
  • 2020-12-10 11:25

    I have found that if the shared key is less than 8 characters, it will return -1.

    0 讨论(0)
  • 2020-12-10 11:26

    Possibly a bit late but try this to connect to Open/WPA/WPA2/WEP secured networks

        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);
    

    Obviously set your own variables for the different security types as applicable. The key (pardon the pun) to connecting to a WEP secured network is the getHexKey method as below.

    /**
     * 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;
    }
    
    0 讨论(0)
  • 2020-12-10 11:35

    I just had this very same problem. Seemingly everything was okay, but then - it wasn't.

    What I found is this:

    • Android WifiStateMachine will not allow you to add or modify networks unless supplicant is running and connected-to. This affects services running on start-up and services running even if WIFI is off.

    • Android WifiConfigStore tracks owners of the wifi network by UID. It means that you may not be able to modify network created by another process.

    The proper way to add a network is:

    1. Check if WIFI network is enabled. If not, call WifiManager.setWifiEnabled(true).
    2. Wait until WifiManager.pingSupplicant() returns true.
    3. Create and fill a new WifiConfiguration, then pass it to WifiManager.addNetwork(). Make sure the value returned is not (-1).
    4. (optional) use value returned by addNetwork() as an argument to WifiConfiguration.enableNetwork() call (unless it's -1). Note, that the boolean parameter means disableOthers and should be false, unless you have right to modify all other networks: it may fail internally, if you set it to true.

    This should allow you to add (and connect) programmatically to a new Wifi network.

    0 讨论(0)
  • 2020-12-10 11:40

    The problem is that you're trying to add the network configuration that already exists. When you call:

    int netId = wifiManager.addNetwork(wc);
    

    it will fail (return -1) if the network configuration with the same SSID already exists. So, what you need to do is to check if netId is -1 and if it is, traverse through the configured networks searching for the network with same SSID and once it's found, return the networkId.

    Kotlin:

    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)
    
    0 讨论(0)
  • 2020-12-10 11:45

    I had the same problem. I found out that your wifi must be on while you are calling addNetwork.

    0 讨论(0)
提交回复
热议问题