WiFI 扫描时选择固定频率(只扫2.4G或者5G的AP)

扫码关注,一起学习
在这里插入图片描述
最近遇到一个新需求,成品如下,就是WiFi扫描界面增加一个选项,可以只扫描2.4G或者5G的AP。
在这里插入图片描述

方案一

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ScanRequestProxy.java
从代码里可以看到WiFi扫描默认是全扫描的,不会对 2.4G 和 5G 做筛选。

public boolean startScan(int callingUid, String packageName) {
    .............
    // always do full scans
    settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
    .............
}

下面是我的修改,frequencyBand 是写入数据库的标志位,UI 界面选择了以后改变这个数据,然后这里读取,再做相应的操作。关于Settings数据库的使用可以看 Settings数据库的使用

private static final String Ap_Frequency_Band = "ap_frequency_band";
public static final int WIFI_BAND_24_GHZ = 1;
public static final int WIFI_BAND_5_GHZ_WITH_DFS  = 6;
public static final int WIFI_BAND_BOTH_WITH_DFS = 7;

public boolean startScan(int callingUid, String packageName) {
    .............
    int frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 0);
    switch (frequencyBand) {
        case WIFI_BAND_24_GHZ:
            settings.band = WifiScanner.WIFI_BAND_24_GHZ;
            break;
        case WIFI_BAND_5_GHZ_WITH_DFS:
            settings.band = WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS;
            break;
        case WIFI_BAND_BOTH_WITH_DFS:
            settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
            break;
        default:
            settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
            break;
    }
        //settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
    .............
}

这么做有一个弊端就是底层依然会扫描,但是上传到 framework 会根据 ScannerSettings 做筛选。这样的话如果你之前连过一个2.4G的AP,现在选择只扫描5G的AP,手机还是会自动重连到你之前保存过的那个2.4GAP,因为底层已经扫描到了。

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java
下面是我在连接网络时做的处理,在连接AP时判断用户选择的频率扫描选项,如果用户选了5G,则连接网络时如果是2.4G的AP则直接返回空,不连接。这样就解决了上面的问题。

private void connectToNetwork(WifiConfiguration candidate) {
    ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate();
    if (scanResultCandidate == null) {
        localLog("connectToNetwork: bad candidate - "  + candidate
                + " scanResult: " + scanResultCandidate);
        return;
    }

添加的代码:

    frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 7);
    if (!((frequencyBand == WIFI_BAND_24_GHZ && scanResultCandidate.is24GHz())
               || (frequencyBand == WIFI_BAND_5_GHZ_WITH_DFS && scanResultCandidate.is5GHz())
               || (frequencyBand == WIFI_BAND_BOTH_WITH_DFS))) {
        return;
    }
    
}

方案二

frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java

后来就想能不能让底层扫描的时候就只扫描某个band的AP呢?结果找到了扫描时 framework 传给底层的参数中就有 freqs 参数,那我修改这个参数不就好了。一看代码果然是不区分,直接全扫描,如何就是修改,和UI通信的方式还是Settings数据库,上面说过了,这里不赘述。

原代码:

public boolean startSingleScan(WifiNative.ScanSettings settings,
        WifiNative.ScanEventHandler eventHandler) {
    synchronized (mSettingsLock) {

        boolean success = false;
        Set<Integer> freqs;
        if (!allFreqs.isEmpty()) {
            freqs = allFreqs.getScanFreqs();
            success = mWifiNative.scan(
                    mIfaceName, settings.scanType, freqs, hiddenNetworkSSIDSet);
            if (!success) {
                Log.e(TAG, "Failed to start scan, freqs=" + freqs);
            }
        } else {
}

channels 是有函数去获取2.4G或者5G对应的频率的,我们把这个写入 freq 就可以。

修改的代码:

public boolean startSingleScan(WifiNative.ScanSettings settings,
        WifiNative.ScanEventHandler eventHandler) {
    synchronized (mSettingsLock) {
        boolean success = false;
   
修改的代码:

        //Set<Integer> freqs;
        int[] channels = null;
        int[] channelDfs = null;
        int frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 7);
        Log.d(TAG, "Ap_Frequency_Band = " + frequencyBand);
        if (!allFreqs.isEmpty()) {
            //freqs = allFreqs.getScanFreqs();
            ArraySet<Integer> mChannels = new ArraySet<Integer>();
			switch (frequencyBand) {
			  case WIFI_BAND_24_GHZ:
			channels = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
			break;
			  case WIFI_BAND_5_GHZ:
			channels = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
			                    channelDfs = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY);
			break;
			  default:
			break;
			}
            if (null != channels){
                for (int chan : channels) {
                    mChannels.add(chan);
                }
                if (null != channelDfs){
                    for (int chan : channelDfs) {
                        mChannels.add(chan);
                    }
                }
                freqs= new ArraySet<Integer>(mChannels);
            } else {
                freqs = allFreqs.getScanFreqs();
            }
            Log.d(TAG, "freqs=" + freqs);
  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值