Android: detect whether wifi access point still in range - android

I have a method to detect available wifi access ppoints. My method works well but when I am not in the range I still getiing the SSID of the last scan results displayed in my xml file though I am out of the range of this SSID.
private void check_wifi_available() {
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (!wifi.isWifiEnabled()) {
Toast.makeText(this, "Please turn your Wi-Fi on",
Toast.LENGTH_SHORT).show();
}
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
final List<ScanResult> results = wifiManager.getScanResults();
if (results != null) {
// list of access points from the last scan
List<ScanResult> updatedResults = new ArrayList<ScanResult>();
// pick Wi-Fi access points which begins with these "SV-"
// characters.
for (int i = 0; i < results.size(); i++) {
String ssid = results.get(i).SSID;
// Pattern p = Pattern.compile("^KD-(4[0-9]{2}|500)$");
// Matcher m = p.matcher(ssid);
// if(m.matches()){}else{}
if (ssid.startsWith("KD")) {
updatedResults.add(results.get(i));
}
}
if (updatedResults.size() > 0) {
String a = deliverBestAccessPoint(updatedResults);
textWifi.setText(a.toString());
}
}
}

This is best handled by the operating system. The best you could do is set up a timer to periodically scan for WiFi devices and update the results.
Other than that, on rooted devices you may be able to manually send 802.11 requests to the access point/router and do a timeout check for replies.
To clarify: the operating system, when it is scanning for devices, sends out a broadcast message and reports what devices it hears back from. When devices are toward the edge of the 'range' they may report as being available even if connecting and maintaining a connection is problematic because the signal is not strong enough.
EDIT:
For what it's worth, ScanResult has a "level" member variable that reports the signal strength. You could do some more fine filtering for low-strength results. http://developer.android.com/reference/android/net/wifi/ScanResult.html

Related

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

Minimum db level of WIFI to communicate with Server in android

i want to send the data to server from an android app. some times i cant able to sync the whole data to server i think because of wifi db level if so what is the minimum db level can i use to start the sync. can anyone please explain me in that.
To get the db of the wifi i am using the following code
WifiManager wifiManager = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> scanResult = wifiManager.getScanResults();
for (int i = 0; i < scanResult.size(); i++) {
Log.d("scanResult", "Speed of wifi"+scanResult.get(i).level);//The db level of signal
}
return info.isConnected();

Android - detecting if wifi is WEP, WPA, WPA2, etc. programmatically

I am looking for a programmatic way on Android to determine whether the WIFI my device is currently connected to is "secured" using either WEP, WPA, or WPA2. I've tried Google searching and I cannot find a programmatic way to determine this. I've also looked at the TelephonyManager (http://developer.android.com/reference/android/telephony/TelephonyManager.html) which also lacks this information.
Thanks,
J
There is a way using the ScanResult object.
Something like this:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
List<ScanResult> networkList = wifi.getScanResults();
//get current connected SSID for comparison to ScanResult
WifiInfo wi = wifi.getConnectionInfo();
String currentSSID = wi.getSSID();
if (networkList != null) {
for (ScanResult network : networkList) {
//check if current connected SSID
if (currentSSID.equals(network.SSID)) {
//get capabilities of current connection
String capabilities = network.capabilities;
Log.d(TAG, network.SSID + " capabilities : " + capabilities);
if (capabilities.contains("WPA2")) {
//do something
} else if (capabilities.contains("WPA")) {
//do something
} else if (capabilities.contains("WEP")) {
//do something
}
}
}
}
References:
http://developer.android.com/reference/android/net/wifi/WifiManager.html#getScanResults()
http://developer.android.com/reference/android/net/wifi/ScanResult.html#capabilities
http://developer.android.com/reference/android/net/wifi/WifiInfo.html
android: Determine security type of wifi networks in range (without connecting to them)
ScanResult capabilities interpretation

Calculating Internet Speed in android

I am working with an App which contains web service things.
In that I need to know the status when the Internet speed is low. How to find the internet speed level in Android?
For example, Consider if I am using 2Mbps connection in my cell phone and when it slows to 50Kbps I need to notice that situation by making a Toast or Alert.
Thanks.
If you are connected to WiFi you can find the speed of the connection using WifiManager :
WifiInfo wifiInfo = wifiManger.getConnectionInfo();
and then from the WifiInfo you can get the current speed :
int speedMbps = wifiInfo.getLinkSpeed();
If you are on 3G, I don't think there is a standard way of finding out, maybe you can assume automatically that 3G is slow.
This is specilally to detect internet connection speed by
facebook sdk
ConnectionQuality cq = ConnectionClassManager.getInstance().getCurrentBandwidthQuality();
This is the code for getting speed of your internet while connected to wifi.
WifiManager wifiManager = (WifiManager)
this.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> wifiList = wifiManager.getScanResults();
for (ScanResult scanResult : wifiList) {
int level = WifiManager.calculateSignalLevel(scanResult.level, 5);
String net=String.valueOf(level);
// Toast.makeText(MainActivity.this,net,Toast.LENGTH_LONG).show();
}
// Level of current connection.here rssi is the value of internet speed whose value
// can be -50,-60 and some others,you can find the speed values easily on internet.
int rssi = wifiManager.getConnectionInfo().getRssi();
int level = WifiManager.calculateSignalLevel(rssi, 5);
String net=String.valueOf(rssi);
Toast.makeText(MainActivity.this,net,Toast.LENGTH_LONG).show();
// -100 is the minimum speed value of your internet.
if(rssi < -100) {
slowInternet=false;
}

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