简体   繁体   中英

Android connecting to hosted network

I'm working on a project in which I am trying to connect a mobile device to a windows hosted network. The android device scans a QR code on the host windows system to get the network SSID and key, connects, then communicates with server software on the windows system to do other fun stuff. The issue I'm running into is that the app is behaving very erratically when connecting to the hosted network; a lot of the time (maybe even most of the time) it connects without any problems. Sometimes I end up connected to a different, preexisting Wifi profile. Other times, my code fails when addNetwork -ing the WifiConfiguration to the WifiManager , and sometimes I seemingly connect but then get a timeout exception thrown when creating the socket.

Apologies for the verbosity, here's the code I have for connecting. The windows hosted network is WPA2, and the issue is definitely not from incorrect SSID and/or key. Thanks in advance for any help, this has been driving me mad!

String contSSID = "SomeSSID";
String contKEY = "SomePassword";

WifiManager wifiManager = (WifiManager) (ontext.getSystemService(Context.WIFI_SERVICE);
boolean addNetwork = true;
int netId = -1;

for (WifiConfiguration tmp : wifiManager.getConfiguredNetworks()) {
    if (tmp.SSID.equals( "\""+contSSID+"\"")) {
        addNetwork = false;
        netId = tmp.networkId;
    }
}
if (addNetwork) {
    WifiConfiguration conf = new WifiConfiguration();
    conf.SSID = "\"".concat(contSSID).concat("\"");
    conf.preSharedKey = "\"".concat(contKEY).concat("\"");
    conf.priority = 40;
    conf.hiddenSSID = false;
    conf.status = WifiConfiguration.Status.ENABLED;
    conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
    conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
    conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
    conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
    conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
    conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
    conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
    for (int i=0; i<10; i++) {
        netId = wifiManager.addNetwork(conf);
        if (netId != -1) {
            Log.d("CAT", "Added network configuration to WifiManager");
            break;
        } else if (i==9) {
            Log.e("CAT", "Error adding network configuration!");
            return "NETCONFIGERROR";
        }
    }
} else {
    Log.d("CAT", "Hosted network has existing profile");
    if (netId == -1) {
        Log.e("CAT", "Existing profile is invalid!");
        return "NETCONFIGERROR2";
    }
}
for (int i=0; i<10; i++) {
    if (wifiManager.setWifiEnabled(true)) {
        Log.d("CAT", "Successfully enabled WiFi");
        break;
    } else if (i==9) {
        Log.e("CAT","Could not enable WiFi!");
        return "WIFIERROR";
    }
}
for (int i=0; i<10; i++) {
    if (wifiManager.disconnect()) {
        Log.d("CAT", "Successfully disconnected from existing networks");
        break;
    } else if (i==9) {
        Log.e("CAT", "Could not disconnect from current WiFi!");
        return "DISCONNECTERROR";
    }
}
boolean enabled = wifiManager.enableNetwork(netId, true);;
for (int i=0; i<10; i++) {
    if (enabled = true) {
        Log.d("CAT", "Network Enabled");
        break;
    }
    enabled = wifiManager.enableNetwork(netId, true);
}
if (!enabled) {
    Log.e("CAT","Could not enable network!");
    return "ENABLEERROR";
}
int j = 0;
while (wifiManager.reconnect() == false) {
    j++;
    if (j>10) {
        Log.e("CAT","Could not reconnect network!");
        return "RECONNECTERROR";
    }
}

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
long startTime = System.currentTimeMillis();
while (networkInfo == null || (networkInfo.isConnected()==false) || networkInfo.getType() != ConnectivityManager.TYPE_WIFI ) {
    networkInfo = connectivityManager.getActiveNetworkInfo();
    if ((System.currentTimeMillis() - startTime) > (30 * 1000)) {
        Log.e("CAT","Error confirming network connection!");
        return "DETECTCONNECTERROR";
    }
            try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        Log.d("CAT", e.getLocalizedMessage());
        Thread.currentThread().interrupt();
    }
}
// Now would come creating the socket and all that.

I also have a few other sleep's in there that I removed to try and manage the ugliness of the code, but I'm quite sure those aren't the issue. Also, this is being run in the background via an AsyncTask . I think that about covers it, any help is much appreciated!

So it looks like my problem all along has been in the line

conf.status = WifiConfiguration.Status.ENABLED;

After omitting this altogether, my code seems to be problem free. I don't think this value is meant to be set manually, but I'm not positive. For anyone suffering from similar problems, I found it very helpful to print conf.toString() if an error occured; in the source code for WifiConfiguration, there's a nifty public int called disableReason which I couldn't access, however when you use toString() it is included unless you are currently connected to the network. The source is as such:

if (this.status == WifiConfiguration.Status.CURRENT) {
    sbuf.append("* ");
} else if (this.status == WifiConfiguration.Status.DISABLED) {
    sbuf.append("- DSBLE: ").append(this.disableReason).append(" ");
}

This is actually the first line printed, and lots of other useful information is provided. It is also helpful if you first manually connect to a network (using android to create the network profile) then use toString() to get all of the specifics of the configuration; that way you can confirm that you were doing it correctly in your WifiConfiguration.

Hope this helps somebody, please post any comments/corrections!

EDIT: I realized this might have been a little unclear; if you have a WifiConfiguration object, eg WifiConfiguration conf in my case, you would simply use conf.toString()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM