Connecting to specific wifi sometimes fails on android - 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();

Related

How do I disable WiFi auto reconnect for a particular SSID programmatically in android?

How can I disable WiFi auto reconnect for a particular SSID programmatically? We can do it manually as given in the screenshot. I wanted to know how can we do it inside of an app.
You can try looking at the android api documentation for the WifiManager here.
a) See WifiNetworkSpecifier.Builder#build() for new mechanism to trigger connection to a Wi-Fi network. b) See addNetworkSuggestions(java.util.List), removeNetworkSuggestions(java.util.List) for new API to add Wi-Fi networks for consideration when auto-connecting to wifi. Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always return -1.
If you then look at removeNetworkSuggestions(java.util.List) Android-API
Remove some or all of the network suggestions that were previously provided by the app. See WifiNetworkSuggestion for a detailed explanation of the parameters. See WifiNetworkSuggestion#equals(Object) for the equivalence evaluation used.
Requires Manifest.permission.CHANGE_WIFI_STATE
So if you've provided a network suggestion with your app, you can also remove this suggestion again. This way, it won't auto reconnect anymore.
Edit: Please also consider this:
If the user uses the Wi-Fi picker to explicitly disconnect from one of
the network suggestions when connected to it, then that network is
ignored when it is still in range. During this period, that network
will not be considered for auto-connection, even if the app removes
and re-adds the network suggestion corresponding to the network.
Try this:
List<WifiConfiguration> lists = wifiManager.getConfiguredNetworks();
for( WifiConfiguration wc : lists ) {
if(wc.SSID != null && wc.SSID.equals("\"" + networkSSID + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(wc.networkId, true);
wifiManager.reconnect();
break;
}
}

Android drops WiFi after connecting programmatically

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!

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

How to regain Net connectivity after losing it?

I'm developing an android app with a capability of connecting to WiFi Networks through it, and everything is OK, I'm creating available WiFi Nets list and the user user one of them to establish connectivity, the following method is the one which is used to establish that connectivity :
int netId;
boolean disableOthers;
wifiManager.enableNetwork(netId, disableOthers);
now I've Two scenarios:
The first one is to set disableOthers to true and that will disable the the connected Network in order to establish a connection with the mentioned one.
The second one is to set disableOthers to false and that will NOT disable the the connected Network and thus the new Network Connection will not be established as there's already a successfully established connection exists.
So, I don't have any options but using case one, but the problem is upon disabling the connected network, if the connection to the new Network fails due to any reason like wrong password or out of range, the device becomes without any Net connection established, So, all I want is a way enables me to regain the previous connection when the aiming to connect to a new one fails.
UPDATE:
Regarding to #bmartins answer, I did the tip the following way :
public static int net_id;
// storing the current connection Net.ID
WifiInfo info = wifiManager.getConnectionInfo();
net_id = info.getNetworkId();
// connecting to the new Net
private void connect(networkId){
wifiManager.disconnect();
wifiManager.enableNetwork(networkId, true);
wifiManager.reconnect();
wifiManager.saveConfiguration();
}
And then when the connection fails:
connect(net_id);
Sounds like a logical issue.
Why not keep track of the last successful netId? If new fails ->
wifiManager.enableNetwork(lastGoodNetId, true);

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