前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WiFI 扫描时选择固定频率(只扫2.4G或者5G的AP)

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

作者头像
用户7557625
发布2020-07-15 11:27:32
1.9K0
发布2020-07-15 11:27:32
举报

最近遇到一个新需求,成品如下,就是WiFi扫描界面增加一个选项,可以只扫描2.4G或者5G的AP。

在这里插入图片描述
在这里插入图片描述

方案一

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

代码语言:javascript
复制
public boolean startScan(int callingUid, String packageName) {
    .............
    // always do full scans
    settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
    .............
}

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

代码语言:javascript
复制
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则直接返回空,不连接。这样就解决了上面的问题。

代码语言:javascript
复制
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数据库,上面说过了,这里不赘述。

原代码:

代码语言:javascript
复制
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 就可以。

修改的代码:

代码语言:javascript
复制
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);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 方案一
  • 方案二
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档