I am writing a program to automatically switch to the strongest WiFi Access Point
where there are access points with same
SSID and different
BSSID.
When there is a Wifi access point available whose signal strength is higher than the currently connected access point, the program should disconnect
the current access point
and reconnect
to the strongest wifi access point available.
In this case, even when I find a wifi network with higher strength
, the current network is not disconnected
or updated to the access point with the strongest
wifi signal.
Hence, there is no automatic switching.
import { Injectable, NgZone } from '@angular/core';
import * as applicationModule from 'tns-core-modules/application';
import * as utils from 'tns-core-modules/utils/utils';
import { config } from '../data/config';
import { WifiCon } from '../interfaces/wifi-con';
import { LoggerService } from './logger.service';
declare var android: any;
@Injectable({
providedIn: 'root'
})
export class WifiConService implements WifiCon {
readonly ssid: string = config.SSID;
readonly password: string = '12345678';
oldBSSID = '';
private readonly ntwkStatus: boolean;
private readonly conBSSID: string;
private readonly ConSubject: any;
private readonly wifiManager: any;
private connectedBSSID = '';
private connectedNetworkId = 0;
private isScanSuccessful = false;
private netId = -1;
private readonly items: Array<Item> = new Array<Item>();
constructor(private readonly zone: NgZone, private readonly logger: LoggerService) {
this.wifiManager = utils.ad.getApplicationContext()
.getSystemService(android.content.Context.WIFI_SERVICE);
this.monitorBSSID();
this.logger.log('Created service for wifi');
}
connectWifi(): boolean {
let isConnected = false;
this.wifiManager.setWifiEnabled(true);
const conf = new android.net.wifi.WifiConfiguration();
conf.SSID = `"${this.ssid}"`;
conf.preSharedKey = `"${this.password}"`;
this.wifiManager.addNetwork(conf);
// const configuredNetworks = this.wifiManager.getConfiguredNetworks();
// for (let i = 0; i < configuredNetworks.size(); i++) {
// // console.log(configuredNetworks.get(i).SSID + " ; ");
// if (configuredNetworks.get(i).SSID !== undefined && configuredNetworks.get(i).SSID === `"${this.ssid}"`) {
// this.wifiManager.disconnect();
// isConnected = this.wifiManager.enableNetwork(configuredNetworks.get(i).networkId, true);
// break;
// }
// }
return isConnected;
}
connectWiFiNetwork(): void {
const wifiConnections = this.items;
this.logger.log(` Connections ${JSON.stringify(wifiConnections)}`);
wifiConnections.sort((a, b) =>
b.strength - a.strength);
this.logger.log(`Sorted Connections ${JSON.stringify(wifiConnections)}`);
if (this.oldBSSID !== wifiConnections[0].bssid) {
let isConnected = false;
// const password = '12345678';
this.wifiManager.setWifiEnabled(true);
// this.wifiManager.enableNetwork(this.wifiManager.getConnectionInfo().getNetworkId(), false);
const conf = new android.net.wifi.WifiConfiguration();
conf.networkId = wifiConnections[0].netId;
conf.BSSID = wifiConnections[0].bssid;
// console.log("Configured Net Id", conf.networkId);
// console.log("Configured BSSID", conf.BSSID);
// console.log("Current network ID", this.wifiManager.getConfiguredNetworks().networkId);
// const isRemoved = this.wifiManager.removeNetwork(this.wifiManager.getConnectionInfo()
// .getNetworkId());
// if (isRemoved === true)
// {
// console.log("Removed network");
// }
// this.connectedNetworkId = this.wifiManager.addNetwork(conf);
this.netId = this.wifiManager.updateNetwork(conf);
// console.log("****************Net Id ", this.connectedNetworkId);
// console.log("****************Current Net Id", this.connectedNetworkId);
isConnected = this.wifiManager.enableNetwork(this.netId, true);
this.wifiManager.reconnect();
this.oldBSSID = wifiConnections[0].bssid;
}
}
disConnectWifi(): boolean {
this.logger.log(`WiFi disconnected
Not connected to "Wi-Fi VLAN"`);
return this.wifiManager.setWifiEnabled(false);
}
getConSubject(): boolean {
return true;
}
switchToStrongNtwk(BSSID: string): boolean {
return true;
}
getNtwkInfo(): any {
return this.wifiManager.getConnectionInfo();
}
isWifiEnabled(): boolean {
return this.wifiManager.isWifiEnabled();
}
monitorBSSID(): void {
const receiverCallback = (androidContext, intent) => {
if (this.isScanSuccessful) {
this.connectedNetworkId = this.getNtwkInfo().getNetworkId();
this.connectedBSSID = this.getNtwkInfo().getBSSID();
this.logger.log('Get Scan Result - ');
const scanResults = this.wifiManager.getScanResults();
this.zone.run(() => {
this.items.length = 0;
for (let n = 0; n < scanResults.size(); n++) {
if (scanResults.get(n).SSID == this.ssid) {
this.items.push({ netId: scanResults.get(n).networkId, ssid: scanResults.get(n).SSID, bssid: scanResults.get(n).BSSID,
strength: scanResults.get(n).level, isConnected: (scanResults.get(n).BSSID === this.connectedBSSID) });
}
}
this.logger.log(`Connections ${JSON.stringify(this.items)}`);
this.connectWiFiNetwork();
});
}
};
applicationModule.android.registerBroadcastReceiver(
android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION,
receiverCallback
);
setInterval(() => {
this.logger.log('Scanning for WiFi Connection');
this.isScanSuccessful = this.wifiManager.startScan();
// console.log("isScanSuccessful", this.isScanSuccessful);
}, config.wifi_scan_time * 1000);
}
}
interface Item {
ssid: string;
bssid: string;
strength: number;
isConnected: boolean;
netId: number;
}
As nobody answered, I'll answer it.
Till android 9 (API level 28), reassociate() will do the job of switching access point without disconnecting from the previously connected access point.
Use this.wifiManager.reassociate()
instead of this.wifiManager.reconnect()
For android 10 and above, the reassociate() and many WifiManager functions are deprecated. Android 10 has introduced a large number of privacy-based changes and restrictions which restrict the enabling and disabling of wifi and direct access to configured Wi-Fi networks. So, programmatically switching access points is not possible.