android-wifi - 如何在 nativescript 中自动切换到具有相同 SSID 但多个 BSSID 的最强 WiFi 接入点?

标签 android-wifi angular2-nativescript wifimanager wifi

我正在编写一个程序来自动切换到最强 WiFi 接入点 那里有接入点,具有相同 SSID不同 BSSID

当有可用的 Wifi 接入点,其信号强度高于当前连接的接入点时,程序应该断开 当前 接入点重新连接 到可用的最强 wifi 接入点。

在这种情况下,即使我找到强度更高的wifi网络,当前网络也不会断开更新 到具有最强 wifi 信号的接入点。

因此,没有自动切换。

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

最佳答案

没人回答,我来回答。 直到 android 9(API 级别 28),reassociate() 将完成切换接入点的工作,而无需断开与先前连接的接入点的连接。 使用 this.wifiManager.reassociate() 而不是 this.wifiManager.reconnect()

对于 android 10 及更高版本,reassociate() 和许多 WifiManager 函数已弃用。 Android 10 引入了大量基于隐私的更改和 restrictions which restrict the enabling and disabling of wifidirect access to configured Wi-Fi networks .因此,无法以编程方式切换访问点。

关于android-wifi - 如何在 nativescript 中自动切换到具有相同 SSID 但多个 BSSID 的最强 WiFi 接入点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59985650/

相关文章:

sockets - native 套接字重新连接

android - String.replace 返回额外的引号

android - wifi 提供商 onLocationChanged 从未被调用

android - 在我的应用程序中使用 GPS、Wi-Fi 时如何节省电量?

http - 什么会导致 Nativescript angular2 中的 promise 失败?

java - Android:即使使用 WifiLock,Wifi 也会关闭

java - 保持连接到没有互联网的网络 - Android

android - 连接到具有相同 SSID 的最强接入点(信号最强的接入点)

java - 在 Android 上使用 Wi-Fi 创建 P2P 连接

android - 工具栏项目颜色(3 点)