in an app, how to swich between access points without loosing connection? - android

Trying to connect to same SSID, but different BSSID (same WiFi, different access point). Now, if I disconnect and reconnect, why do I still have to find the best signal? By default, it will connect to best signal (closest) access point. How can I connect to best signal without disconnecting and reconnecting?
I'm using wifimanager to find my network and my access points. I can find all my access points and their BSSID and their signal level. Now, in order to connect to best signal, I need to disconnect and reconnect, this will make my app to loose connection for a while, until reconnects.
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
List<ScanResult> wifiList = wifiManager.getScanResults();
ArrayList<String> deviceList = new ArrayList<>();
for (ScanResult scan_wifi_results : wifiList) {
if (scan_wifi_results.SSID.equals("Office")||scan_wifi_results.SSID.equals("Warehouse")) {
if (bestSignal == null || WifiManager.compareSignalLevel(bestSignal.level, scan_wifi_results.level) < 0) { bestSignal = scan_wifi_results; }
deviceList.add(scan_wifi_results.SSID + " - db: " + scan_wifi_results.level + " - Mac: " + scan_wifi_results.BSSID); }
}
ArrayAdapter arrayAdapter = new ArrayAdapter(context, R.layout.wifi_template, deviceList.toArray());
wifiDeviceList.setAdapter(arrayAdapter);
}
WifiConfiguration config = new WifiConfiguration();
config.SSID = bestSignal.SSID;
config.BSSID = bestSignal.BSSID;
netID = wifiManager.addNetwork(config);
}
wifiManager.disconnect();
wifiManager.enableNetwork(netID,true);
wifiManager.reconnect();
Toast.makeText(context,"Connected to best Signal: " + bestSignal.BSSID,Toast.LENGTH_SHORT).show();
}
if I add wifiManager.enableNetwork(netID,true) without disconnect and reconnect, it will not change access point
Is possible to accomplish that without loosing wifi connection?

Related

Android wifiManager.enableNetwork(j.networkId, true) is switching back to previous network

I have to show list of access points (with no internet) and then connect to a selected network. I was able to get all available network network with wifiManager.getScanResults() then i have filtered my preferred open network and configured with wifiManager.addNetwork(conf);then i am trying to connect that preferred network with wifiManager.enableNetwork(j.networkId, true) It connecting to That network and again switching back to previous network.
1) the selected network gets connected
2) then its disconnected after couple of seconds
3 )wifi connects to the previously connected network
The behavior is only observed in Android devices with OS above 7.0. Marsh mellow and below device it is not switching network
here is my code
1 ) scanning and configuring
if (netType == ConnectivityManager.TYPE_WIFI) {
//wifiManager =
(WifiManager)this.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> results = wifiManager.getScanResults();
if (!results.equals(null)) {
for (int i = 0; i < results.size(); i++) {
ScanResult result = results.get(i);
if(result.SSID.toLowerCase().startsWith("XXXX.")) {
list.add(result.SSID);
conf =new WifiConfiguration();
conf.SSID = "\"" + result.SSID + "\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiManager.addNetwork(conf);
}
}
}
2) to connect preferred network
if (j.SSID != null && j.SSID.equals("\"" + XXXXXX+ "\"")) {
Log.d("Config", "" + j.SSID);
wifiManager.disconnect();
wifiManager.enableNetwork(j.networkId, true);
wifiManager.reconnect();
break;
}

Connect to WiFi Which Doesn't Have Internet

I'm trying to connect to a WiFi hotspot (open network) which doesn't have Internet access when the app starts.
However, there's another saved Wifi which has Internet. When I turn on Wifi, it always connects automatically to the one with Internet access.
I have been trying to fix this issue for like a week now! But nothing is working. In fact, my code disconnects from the network with internet but doesn't connect to the network I want. It doesn't make sense.
On the WiFi settings activity, it says "No Internet detected. Won't reconnect automatically."
private boolean tryConnect(WifiManager wifiManager, List<ScanResult> scanResults) {
for (ScanResult scanResult : scanResults) {
Log.d(TAG, "SCAN-RESULT: " + scanResult);
if (scanResult.SSID.toLowerCase().contains(MainActivity.ARDRONE2_HOTSPOT_NAME) && WifiUtilities.getScanResultSecurity(scanResult) == WifiUtilities.NetworkSecurity.OPEN) {
Log.d(TAG, "Trying Connecting to ARDrone2");
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.SSID = String.format("\"%s\"", scanResult.SSID);
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wifiConfiguration.priority = Integer.MAX_VALUE - 1;
List<WifiConfiguration> wifiConfigList = wifiManager.getConfiguredNetworks();
int networkId = -1;
for (WifiConfiguration wifiConfig : wifiConfigList) {
if (wifiConfig != null) {
if (wifiConfig.SSID.equals("\"" + scanResult.SSID + "\"")) {
networkId = wifiConfig.networkId;
} else {
wifiManager.disableNetwork(wifiConfig.networkId);
}
}
}
if (networkId == -1) {
networkId = wifiManager.addNetwork(wifiConfiguration);
} else {
networkId = wifiManager.updateNetwork(wifiConfiguration);;
}
wifiManager.saveConfiguration();
wifiManager.disconnect();
wifiManager.enableNetwork(networkId, true);
wifiManager.reconnect();
return true;
}
}
return false;
}
The debug log: "Trying Connecting to ARDrone2" appears and yet it doesn not connect!!!
A similar question has been asked here Android, automatically connecting to wifi networks that have no internet access but no comments or answers were provided.
It seems like the problem was with my own phone. I have CM13.0 and apparently they don't allow connecting to networks that don't have Internet access. Even manual connecting to a network without Internet is a lot of trouble.
I tried it on other phones with non-custom ROMs and they all worked as expected according to the code above:
Disable all saved networks (this could be improved)
Disconnect from currently connected network
Connect to the ARDrone2

Android Wifi Roaming through AP with same SSID

I saw that Android system has a bad behavior with Wifi roaming.
We have a Wifi centralized network with many AP with a signle SSID.
The Adroid Phones wont roams seamlessly.
An Android Phone tries to stay connected to an AP until the signal reaches zero even if there are others AP (with the same SSID) with a good signal!
When the signal is zero, finally it performs an assosiation to another AP (with a good signal). But with this behavior the phone loses all the TCP Connections!
For example:
the phone is connected in WiFi to AP1
the phone moves in the building and now hears two signals from AP1 and from AP2.
When the signal form AP2 is stronger than the signal from AP1, i want that the phone do a reassosiation (not an assosiation) to AP2.
The idea is:
Perform a WifiManager.startScan()
Get the results WifiManager.getScanResults()
Find the best AP in the results
Perform a reassosiation to the best AP
Repeat every 30 seconds.
I talk about reassosiation because i don't want that the phone loses the TCP Connections.
There is a way to do this ?
Thank you,
Salvo
You cannot do this as you describe. A client cannot determine the state of the TCP connection on it's own. Your network must also move the communication channel from one AP to another. This can be done with the right network controllers.
Also, you should look at IEEE 802.11k -
https://en.wikipedia.org/wiki/IEEE_802.11k-2008
Add below permissions;
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Register for below intent;
private WifiBroadcastReceiver wifiBroadcastReceiver = new WifiBroadcastReceiver();
Then in routine;
registerReceiver(wifiBroadcastReceiver, new IntentFilter("android.net.wifi.SCAN_RESULTS"));
Use the below class to change the reassociation;
public class WifiBroadcastReceiver extends BroadcastReceiver {
private WiFiManager manager = null;//set the value in constructor
private WifiConfiguration connectedConfiguration = null;//set the value in constructor
private int connectedNetId;
private void updateConnectedConfiguration(String ssid) {
configs = manager.getConfiguredNetworks();
int nid = 0;
for (WifiConfiguration cnf : configs) {
if (cnf.SSID.substring(1, cnf.SSID.length() - 1).equals(ssid)) {
connectedConfiguration = cnf;
connectedNetId = nid;
}
nid++;
}
}
public void onReceive(Context c, Intent intent) {
List<ScanResult> results = manager.getScanResults();
WifiInfo info = manager.getConnectionInfo();
ScanResult stronger = null;
for (ScanResult scanResult : results) {
try {
if (scanResult.SSID.equals(info.getSSID())) {
if (stronger == null) {
if (WifiManager.compareSignalLevel(info.getRssi() + 5, scanResult.level) < 0) {
stronger = scanResult;
}
} else if (WifiManager.compareSignalLevel(stronger.level, scanResult.level) < 0) {
stronger = scanResult;
}
}
} catch (Exception e) {
}
}
if (stronger != null && !stronger.BSSID.equals(info.getBSSID())) {
updateConnectedConfiguration(info.getSSID());
if (connectedConfiguration != null) {
connectedConfiguration.BSSID = stronger.BSSID;
manager.updateNetwork(connectedConfiguration);
manager.saveConfiguration();
manager.enableNetwork(connectedNetId, true);
manager.reassociate();
info = manager.getConnectionInfo();
//showNotification("\nConnecting " + stronger.SSID, stronger.BSSID + " " + stronger.level + "dBm");
}
}
}
}

How to view list of devices that is connected to my router and select one of them then send and receive data from it

I am new to android application development and I want to build an application that uses wifi to connect to another devices (not mobile devices) and sends some data from my phone to a device and receives some data from the other device.
What I have in my local network:
mobile phone support wifi with android os.
device support wifi connection (e.g. temperature sensor).
What I need:
The phone needs to connect to the router and receive a list of available devices and check if the sensor is connected to the network or not.
Connect to the sensor and send a message from the phone that tells the sensor to measure the temperature.
The sensor sends back a message that contains the temperature.
Your question is nor quite clear to me. But as per my understanding you want to list down some Wi-Fi enabled devices on your mobile & then connect to one of them & finally communicate with them.
For Listing all access points you have to implement the code below.
private final BroadcastReceiver mWifiScanReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
List<ScanResult> scanResults = mainWifiObj.getScanResults();
mScannedNetworksAdapter.clear();
listView_Access_point.clearChoices();
if (scanResults != null) {
for (ScanResult result : scanResults) {
mScannedNetworksAdapter.add(result)
}
}
listView_Access_point.setAdapter(mScannedNetworksAdapter);
}
}
};
Now After listing all the Wi-Fi access points you have to click one of them to get connected. To do this you have implement OnItemClickListener & then override onItemclick(). See the code below.
#Override
public void onItemClick(AdapterView<?> parent, View arg1, int position, long arg3) {
ScanResult result = (ScanResult) parent.getItemAtPosition(position);
WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + result.SSID + "\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
wifiManager.addNetwork(conf);
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
if(list!=null){
for( WifiConfiguration i : list ) {
if(i.SSID != null && i.SSID.equals("\"" + result.SSID + "\"")) {
wifiManager.disconnect();
wifiManager.enableNetwork(i.networkId, true);
wifiManager.reconnect();
break;
}
}
}
}
Then you have to implement a BroadcastReceiver which tells if the access point is connected successfully.
private final BroadcastReceiver mWifiConnectionEstablished = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent intent) {
String action = intent.getAction();
if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
NetworkInfo nwInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (NetworkInfo.State.CONNECTED.equals(nwInfo.getState()) && nwInfo.isConnected()) {
//The connection is established. Now do your stuff here
}
}
}
};
Finally there are several methods for communication. One of them is socket communication. You will get several examples in google for socket communication in android.

How to find all WiFi networks that are not in range?

I am writing an application to display the WiFi network types and status. How do I find all the "not in range" WiFi networks? Is it possible to get the list of all configured (previously seen) WiFi networks that are out of range?
I used the below code to get the result
WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
List<ScanResult> results = mWifiManager.getScanResults();
if (configs != null) {
for (WifiConfiguration config : configs) {
for (ScanResult result : results) {
if (result.SSID == null || result.SSID.length() == 0) {
continue;
}
else {
if (result.SSID.equals(MyString.removeDoubleQuotes(config.SSID))) {
int level = mWifiManager.CalculateSignalLevel(result.level, 4);
Log.d("MyApp", Config.SSID + " " + level);
}
}
}
}
}
But if configured network is high in number then it will take long time to execute. Is there any way to optimize this problem? By getting the scanned result of only the configured network.
How about subtracting the wifi networks in range from all wifi networks?

Categories

Resources