Android drops WiFi after connecting programmatically - android

I am experiencing a strange behavior in my Android app: Every time I connect programmatically to a WiFi network (source see below), first it works as intended, but after a couple of seconds (between 5 and around a minute) the connection is dropped and the device tries to connect to another network.
If I, however, connect to the same network manually (i.e. through Android's Settings App), everything works as intended and the device stays connected to the AP (I have cleared the WifiConfiguration-list, so there is only occurrence of the desired SSID).
Here is the relevant part of the code I use to connect to the network:
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
String ssid = "NameOfAP";
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for (WifiConfiguration i : list) {
if (i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
break;
}
}
Some additional info:
Lenovo Yoga Tablet 2 with Android 5.0.1 (since it is an in-house app which only runs on this device)
The network is not connected to the internet (though the captive portal detection flag is set to disabled/0)
I have tried to look at Android's code in Lollipop, but they are using wifiManager.connect(), which I somehow cannot access.
Any help appreciated!

Related

BindProcessToNetwork not working on a specific device

I have an app that's custom built for a client and not available in the Play Store that basically makes some network calls when it detects that the device is connected to their WiFi. This should happen even if it has no internet connection, every request that the app makes is to a local address.
The problem comes with the new batch of tablets that the client has purchased (Galaxy Tab Active 2, Android 8.1.0, Build number M1AJQ.T395XXU3BRJ5), which will always prefer a connection with internet access over whatever network I'm telling it to bind to.
WiFi -> Advanced -> Switch to mobile data is already disabled, so that should not be it.
Here's the code I'm using that has been working until now:
ConnectivityManager cm = (ConnectivityManager) getApplication().getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
for (int i = 0, networksLength = networks.length; !bound && i < networksLength; i++) {
Network network = networks[i];
if (correctNetwork(network)) { //SSID check
bound = cm.bindProcessToNetwork(network);
Log.i(TAG, "Bound? " + bound);
}
}
On all their previous devices, my own phone and even a Galaxy Tab Active 1 this is working: we see "Bound? true" in the logs and every connection is made through the right network. On the Active 2 we always see "Bound? false" and it will use the 4G connection. Disabling data is not an option.
If this is a Samsung bug, is there a workaround for it? Or maybe an alternative way of forcing an HttpURLConnection to use a specific network?

Connecting to specific wifi sometimes fails on android

I am creating an app, which can list out all the available wifi's in a ListView. If I select one of the wifi's in the list, which was cached before in List<WifiConfiguration> list = wifiManager.getConfiguredNetworks(); then it should connect to it. If the WifiConfiguration list doesn't contain the selected wifi, then nothing happens. My problem is, that sometimes I select a wifi from the list (which I know for sure is in the WifiConfiguration list), but it doesn't connects to it. Instead it connects back to the previously connected wifi. After some attempts (selecting again and again the same wifi) it connects to it finally. This doesn't happen always, just sometimes. What can be the problem? Here is my code snippet:
// Go through all the cached wifis and check if the selected GoPro was cached before
for (WifiConfiguration config : configurations) {
// If it was cached connect to it and that's all
if (config.SSID != null && config.SSID.equals("\"" + mDrawerListView.getAdapter().getItem(position) + "\"")) {
// Log
Log.i("onReceive", "Connecting to: " + config.SSID);
mWifiManager.disconnect();
mWifiManager.enableNetwork(config.networkId, true);
mWifiManager.reconnect();
break;
}
}
This is what's going on. Basically, you can tell the OS to disable a network, and you can tell the OS to enable a network, but it's not possible to tell the OS what network to connect to.
If there are multiple WiFi access points in range that are both configured on the device (and both are in the enabled state), the OS will decide which one to connect to.
The only way to force the OS to connect to one of the networks in range instead of the other one is to call disableNetwork() on the network that is in range that you don't want to connect to.
Let's go through your code line by line:
mWifiManager.disconnect();
The line above tells the OS to disconnect from the currently connected WiFi access point.
mWifiManager.enableNetwork(config.networkId, true);
The line above tells the device to set the network to the enabled state if it was previously in the disabled state.
mWifiManager.reconnect();
From the documentation:
Reconnect to the currently active access point, if we are currently
disconnected. This may result in the asynchronous delivery of state
change events.
So, when you say Instead it connects back to the previously connected wifi., it's working exactly as expected, as the OS is re-connecting to what it considers the currently active access point.
If you really want to disable the other network so that the OS will connect to the one you just clicked on, you could do something like this:
// Go through all the cached wifis and check if the selected GoPro was cached before
WifiInfo info = mWifiManager.getConnectionInfo(); //get WifiInfo
int id = info.getNetworkId(); //get id of currently connected network
for (WifiConfiguration config : configurations) {
// If it was cached connect to it and that's all
if (config.SSID != null && config.SSID.equals("\"" + mDrawerListView.getAdapter().getItem(position) + "\"")) {
// Log
Log.i("onReceive", "Connecting to: " + config.SSID);
mWifiManager.disconnect();
mWifiManager.disableNetwork(id); //disable current network
mWifiManager.enableNetwork(config.networkId, true);
mWifiManager.reconnect();
break;
}
}
Hi instead of disabling the previous network , you can change the priority of the network you to connect to greater than all other configured networks and then when you reconnect() . it will connect to the highest priority network in range.
wificonfig.priority = 10000;
wifiManager.updateNetwork(wificonfig);
wifiManager.saveConfiguration();
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, false);
wifiManager.reconnect();

android cant connect to wifi network programatically (drops after few seconds and come back to previous one)

I am trying to connect to a wifi network programatically. Android connects to it, but after few seconds it drops the connection and automatically connects to the previous one.
If i try to connect through the settings, android connects to my desire network and stay connected.
Am I missing something?
The wifi network the I am trying to connect does not have internet access. It is a open network created by arduino + esp8266. I am trying to do something like the configuration method of chromecast.
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = "\"" + iotWifi + "\"";
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.priority = 40;
int res = wifiManager.addNetwork(wifiConfiguration);
wifiManager.saveConfiguration();
wifiManager.disconnect();
wifiManager.enableNetwork(res, true);
wifiManager.reconnect();
with android lP version, android checks the network internet status and if connected network do not have internet and in previous connected network(any of) have internet ,Android device gives preference to internet enable network.

Android connect to Wi-Fi AP when screen is off

I'm working on a project which need to connect to a Wi-Fi in a background service, the service running when the device is screen off.
The connecting code is like below:
public boolean connect_android(String ssid) {
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
boolean find = false;
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.equals("\"" + ssid + "\"")) {
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
find = true;
break;
}
}
while after the connecting code is executed in the background running service, the device never connect to the Wi-Fi successfully until the screen is turned on. I logged the supplicant state, it is in complete state. As the google docs says:
This state indicates that the supplicant has completed its processing for the association phase and that data connection is fully configured. Note, however, that there may not be any IP address associated with the connection yet. Typically, a DHCP request needs to be sent at this point to obtain an address.
So can i come to the conclusion that, when the screen is turned on, a DHCP request is send the device receives an IP and the connection is complete successfully. But who is in charge of sending the DHCP, the wpa_supplicant or Android framework, is there any docs about this? How can i connect to a Wi-Fi AP without turn on the screen? Thanks in advance!
Maybe because your device use feature turn of wifi when screen of (Settings -> Wireless and network -> WiFi settings -> (menu button) Advanced -> Wifi sleep policy)
Your app will cannot connect to network

connecting to wifi in Android

I am working on an android application which involves connecting to a specific wifi when in range. Once I am done doing some stuff, I am trying to connect back to my original wifi. For some strange reason, it connects to my original wifi as I want it to, but after about 30 seconds or so, it drops the connection. When I check my wifi settings on the device it shows that wifi as disabled.
To sum up:
1. Connect to Wifi W1.
2. When Wifi W2 is in range, connect to that (using the SSID) but, remember the SSID of W1 for later.
3. Disconnect from W2 and look for W1 in wificonfiguration list (using SSID). When found, connect to that.
All three steps are working, but for some reason, a short while after step 3 succeeds (< 1 minute)the connection to W1 is dropped and disabled by the device. This only happens when I change wifi connections through code. Here's what my code looks like:
the 'net' variable contains the SSID value of the original wifi connection's SSID (W1). Does anyone have any idea why I would be dropping connection shortly after reconnecting to the original Wifi?
if(net!=""){
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.contains(net)) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.setWifiEnabled(true);
break;
}
}
}
I have a suggestion which I am not sure if this is going to solve the problem or not but it would be worth trying
in the below code if you place
if(net!=""){
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.contains(net)) {
wifiManager.disconnect();
//place a sleep on thread so that the underlying hardware gets some time to disconnect
Thread.sleep(10000);
//Now trying connecting to the previous network. Also try increasing the time to wait if 5 seconds is not working.
wifiManager.enableNetwork(i.networkId, true);
wifiManager.setWifiEnabled(true);
break;
}
}
}
EDIT:
It seems to work with the interval more than 10seconds. This time interval is i think dependent on the WiFi Chipset of the device, it needs some time to disconnect from the current network and to be connected to other. Also If the device has a low quality chipset then it might take longer Also I reckon if the device has a high quality chipset then it will be much quicker..

Categories

Resources