【Android13开发WIFI添加频段设置项(2.4G/5G/automatic)更改笔记】

您所在的位置:网站首页 荣耀v10wifi频段设置 【Android13开发WIFI添加频段设置项(2.4G/5G/automatic)更改笔记】

【Android13开发WIFI添加频段设置项(2.4G/5G/automatic)更改笔记】

2024-07-14 01:28| 来源: 网络整理| 查看: 265

BUG需求描述:

提示:这里简述项目相关背景:

Android13中客户需求添加WIFI频段选项: 2.4G only,只显示链接2.4G的AP。 5G only,只能显示和链接5G的AP。 Automatic:自动显示,即全部正常显示。

解决初衷

提示:这里描述项目中遇到的问题:

作为初学者的我,刚开始接到这个bug,还是比较懵的,多亏了CSDN的前辈发表的文章给予我很大的帮助。站在巨人的肩膀上看的更远,我在前辈的文章上进一步添加自己的理解,剖析其中的逻辑,希望能给大家提供帮助!

你需要具备有关WIFI的一点小知识

1.android wifi scanresult.接口 ScanResult类实现Parcelable接口:ScanResult类描述了一个已发现AP的信息。除了在该类中描述的属性,supplicant还跟踪了quality(品质),noise(噪声),maxbitrate(最大比特率)属性,但是并不立刻将它们通知给客户端。 2.1.目录位置: /frameworks/base/wifi/java/android/net/wifi/

3.WIFI频段中24G和5G核心方法 1.public boolean is24GHz():直接调用is24GHz(frequency),即用自己的信道频率值进行判断,如果频率值在2400~2500之间,(不包括2400和2500两个边界值),则返回true,否则返回false。

2.public boolean is5GHz(int freq):用传入的freq值进行判断,若在4900~5900之间,不含边界,则返回true,否则返回false。

更改后的样式展示

添加三级菜单_WIFI frequency band 点击WIFI frequency band设置项后弹出提示选项框

实现思路

设置页面里使用ListPreference静态增加"WLAN频段"菜单项,通过选项将设定的wifi频段值保存在settings数据库中,最后在WifiManager里处理其中的逻辑。

代码实现步骤(保姆式教学):

1.首先第一步骤需要在相应的布局位置添加相应的布局。 system/vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/wifi_configure_settings.xml

资源文件需在strings.xml中单独配置

布局页面位置 布局显示

2.vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/arrays.xml 添加相应的数组和添加相应的选项

Automatic 2.4 GHz only 5 GHz only 2 1 0

参考文章添加位置 选项位置

3.新增控制文件 system/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/wifi/WifiFrequencyBandPreferenceController.java

package com.android.settings.wifi; import android.content.Context; import android.net.wifi.WifiManager; import android.provider.Settings; import android.util.Log; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.xchengtech.ProjectConfig; public class WifiFrequencyBandPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener { private static Context mContext; private WifiManager mWifiManager; public String getPreferenceKey() { return "wifi_frequency_options"; } public boolean isAvailable() { return true; //可以设置相应宏控判定该模块是否呈现 } public WifiFrequencyBandPreferenceController(Context context, Lifecycle lifecycle, WifiManager wifiManager) { super(context); mContext = context; this.mWifiManager = wifiManager; } public void displayPreference(PreferenceScreen preferenceScreen) { super.displayPreference(preferenceScreen); ListPreference listPreference = (ListPreference) preferenceScreen.findPreference("wifi_frequency_options"); int frequencyBand = getFrequencyBand(); listPreference.setValue("" + frequencyBand); updateFrequencyBandSummary(listPreference, "" + frequencyBand); } public boolean onPreferenceChange(Preference preference, Object obj) { String str = (String) obj; int parseInt = Integer.parseInt(str); updateFrequencyBandSummary((ListPreference) preference, str); boolean b = Settings.Global.putInt(mContext.getContentResolver(), "wifi_frequency_band", parseInt); if (b) { if (null != mWifiManager) { if (mWifiManager.isWifiEnabled()) { mWifiManager.setWifiEnabled(false); mWifiManager.setWifiEnabled(true); }else{ mWifiManager.setWifiEnabled(true); mWifiManager.setWifiEnabled(false); } } } return true; } private int getFrequencyBand() { return Settings.Global.getInt(mContext.getContentResolver(), "wifi_frequency_band", 2); } private void updateFrequencyBandSummary(ListPreference listPreference, String str) { listPreference.setSummary(listPreference.getEntries()[listPreference.findIndexOfValue(str)]); } }

4.在WIFI设置项中的控制类添加相应的控制模块 system/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/wifi/ConfigureWifiSettings.java

@Override protected List createPreferenceControllers(Context context) { final WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); final List controllers = new ArrayList(); controllers.add(new WifiP2pPreferenceController(context, getSettingsLifecycle(), wifiManager)); /// M: For wapi cert manager feature @{ controllers.add(new WapiCertPreferenceController(context)); /// @} //add by wjj for wifi frequency options start controllers.add(new WifiFrequencyBandPreferenceController(context, getSettingsLifecycle(), wifiManager)); //add by wjj for wifi frequency options end return controllers; } @Override public void onAttach(Context context) { super.onAttach(context);

5.核心逻辑实现类在wifimanager.java类中的getScanResults()方法中 首先现在最上方设置相应的宏定义 system/packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java

//wjj add final int wifi_band_5_ghz = 0; final int wifi_band_24_ghz = 1; final int wifi_band_5_24ghz = 2; //wjj end

再在相应的方法中添加相应的判断逻辑

/** * Return the results of the latest access point scan. * @return the list of access points found in the most recent scan. An app must hold * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * and {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission * in order to get valid results. */ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, ACCESS_FINE_LOCATION}) public List getScanResults() { try { //add by wjj for wifi frequency options start if (true) { //此处可以进一步设置判断 List results = mService.getScanResults(mContext.getOpPackageName(),mContext.getAttributionTag()); //设置scanResult类型的列表 result 获取每一条wifi字段包含许多属性 int wifiFrequency = Settings.Global.getInt(mContext.getContentResolver(), "wifi_frequency_band", 2); //wifiFrequency 只获取其中的频段 if(results != null && results.size() > 0){//判空逻辑,列表不为空则进行下一步 WifiInfo wifiInfo = getConnectionInfo();//获取所有可以链接的项(我的理解) Iterator iterator = results.iterator();//迭代器进行遍历 while (iterator.hasNext()) {//迭代器结果判断 ScanResult result = iterator.next(); if(ScanResult.is24GHz(result.frequency) && (wifiFrequency == wifi_band_5_ghz)){//异常值即频段只有2.4G但band等级达到5G的异常值(不是很懂怎么表述,希望大佬指正)意思大概就是异常值移除 iterator.remove();//移除操作 if (ScanResult.is24GHz(wifiInfo.getFrequency())) {//符合2.4G disableEphemeralNetwork(wifiInfo.getSSID());//隐藏相应的显示信息 disconnect();//断开链接 } } if((ScanResult.is5GHz(result.frequency) || result.frequency >= 5900 ) && (wifiFrequency == wifi_band_24_ghz)){//符合5G频段或6G但wifi等级却是2.4G的异常值移除 iterator.remove(); if (ScanResult.is5GHz(wifiInfo.getFrequency()) || result.frequency >= 5900) {//符合5G或以上条件的 disableEphemeralNetwork(wifiInfo.getSSID());//隐藏 disconnect();//断开链接 } } } } return results; } else {//扫描结果全部进行显示 return mService.getScanResults(mContext.getOpPackageName(), mContext.getAttributionTag()); } //add by wjj for wifi frequency options end } catch (RemoteException e) {//异常处理 throw e.rethrowFromSystemServer(); } }

Bug优化1:解决wifi频率切换时,有时不会自动断开或重新连接 1.system/packages/modules/Wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java

/** * Handles 'onResult' callbacks for the Periodic, Single & Pno ScanListener. * Executes selection of potential network candidates, initiation of connection attempt to that * network. */ private void handleScanResults(@NonNull List scanDetails, @NonNull String listenerName, boolean isFullScan, @NonNull HandleScanResultsListener handleScanResultsListener) { //add by wjj for wifi frequency options start Iterator iterator = scanDetails.iterator(); int wifi_frequency_band = Settings.Global.getInt(mContext.getContentResolver(), "wifi_frequency_band", 2); while (iterator.hasNext()) { ScanDetail result = iterator.next(); ScanResult sr = result.getScanResult(); if ((!ScanResult.is24GHz(sr.frequency) && (wifi_frequency_band == wifi_band_24_ghz)) || (!ScanResult.is5GHz(sr.frequency) && wifi_frequency_band == wifi_band_5_ghz)) { iterator.remove(); } } //add by wjj for wifi frequency options end List cmmStates = new ArrayList(); Set connectedSsids = new HashSet(); boolean hasExistingSecondaryCmm = false; for (ClientModeManager clientModeManager : mActiveModeWarden.getInternetConnectivityClientModeManagers()) { if (clientModeManager.getRole() == ROLE_CLIENT_SECONDARY_LONG_LIVED) { hasExistingSecondaryCmm = true; } mWifiChannelUtilization.refreshChannelStatsAndChannelUtilization( clientModeManager.getWifiLinkLayerStats(), WifiChannelUtilization.UNKNOWN_FREQ); WifiInfo wifiInfo = clientModeManager.syncRequestConnectionInfo(); if (clientModeManager.isConnected()) { connectedSsids.add(wifiInfo.getSSID()); } cmmStates.add(new WifiNetworkSelector.ClientModeManagerState(clientModeManager)); } // We don't have any existing secondary CMM, but are we allowed to create a secondary CMM // and do we have a request for OEM_PAID/OEM_PRIVATE request? If yes, we need to perform // network selection to check if we have any potential candidate for the secondary CMM // creation. if (!hasExistingSecondaryCmm && (mOemPaidConnectionAllowed || mOemPrivateConnectionAllowed)) { // prefer OEM PAID requestor if it exists. WorkSource oemPaidOrOemPrivateRequestorWs = mOemPaidConnectionRequestorWs != null ? mOemPaidConnectionRequestorWs : mOemPrivateConnectionRequestorWs; if (oemPaidOrOemPrivateRequestorWs == null) { Log.e(TAG, "Both mOemPaidConnectionRequestorWs & mOemPrivateConnectionRequestorWs " + "are null!"); } if (oemPaidOrOemPrivateRequestorWs != null && mActiveModeWarden.canRequestMoreClientModeManagersInRole( oemPaidOrOemPrivateRequestorWs, ROLE_CLIENT_SECONDARY_LONG_LIVED, false)) { // Add a placeholder CMM state to ensure network selection is performed for a // potential second STA creation. cmmStates.add(new WifiNetworkSelector.ClientModeManagerState()); hasExistingSecondaryCmm = true; } }

2.自己添加的控制类中完善 system/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/wifi/WifiFrequencyBandPreferenceController.java

public boolean onPreferenceChange(Preference preference, Object obj) { String str = (String) obj; int parseInt = Integer.parseInt(str); updateFrequencyBandSummary((ListPreference) preference, str); boolean b = Settings.Global.putInt(mContext.getContentResolver(), "wifi_frequency_band", parseInt); if (b) { if (null != mWifiManager) { if (mWifiManager.isWifiEnabled()) { mWifiManager.setWifiEnabled(false); mWifiManager.setWifiEnabled(true); //add by wjj for wifi frequency options start mWifiManager.startScan(); //add by wjj for wifi frequency options end }else{ mWifiManager.setWifiEnabled(true); mWifiManager.setWifiEnabled(false); } } } return true; }

Bug优化2:这个是前辈优化步骤值得借鉴 对于双频合一的wifi优化:android13中如果未对双频wifi优化,当选择2.4g频段时,连接双频合一wifi,此wifi不是2.4g频率(还是5g频率),正常现象应该是连上双频合一wifi2.4g频率的。

public boolean startSingleScan(WifiNative.ScanSettings settings, WifiNative.ScanEventHandler eventHandler) { if (eventHandler == null || settings == null) { Log.w(TAG, "Invalid arguments for startSingleScan: settings=" + settings + ",eventHandler=" + eventHandler); return false; } synchronized (mSettingsLock) { if (mLastScanSettings != null) { Log.w(TAG, "A single scan is already running"); return false; } ChannelCollection allFreqs = mChannelHelper.createChannelCollection(); boolean reportFullResults = false; for (int i = 0; i = settings.hiddenNetworks.length || !executeRoundRobin) { mNextHiddenNetworkScanId = 0; } if (DBG) { Log.d(TAG, "Scanning for " + numHiddenNetworksPerScan + " out of " + settings.hiddenNetworks.length + " total hidden networks"); Log.d(TAG, "Scan hidden networks starting at id=" + mNextHiddenNetworkScanId); } int id = mNextHiddenNetworkScanId; for (int i = 0; i reportScanFailure()); } } return true; } } 总结:

1.Android 10 或更高版本为目标平台的应用调用WifiManager相关api(setWifiEnable、startScan、getScanResults等方法)不会生效,会返回false 2.调用Wi-Fi信息需要以下权限 添加位置在settings的菜单文件中(一般都有加)

最后的总结:

伙伴们,我是参考一位叫ysliu的前辈的,在他的基础上进行进一步的补充,作为刚入职场的人来说,太需要这样板书十分仔细的前辈了,如果您看到这里啦,可以再去看看前辈写的东西,真的很详细 前辈的CSDN。希望我记录的这些东西能够帮助到更多的人吧!–一位初入职场大学学大数据的android开发从业者。

前辈更多优秀文章的链接(上方超链接也可以哈):

Lysssx前辈



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3