Android13 热点默认5G频道配置修改_android 系统 wifi ap热点功能配置方式

//(1)获取默认配置信息方法,该方法在系统无法检测到默认配置文件时会生成
//系统第一次运行时会执行到,还有就是把系统热点配置文件删除后再重启也是会执行到
private SoftApConfiguration getDefaultApConfiguration() {
    SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
    //configBuilder.setBand(generateDefaultBand(mContext)); //(2)原来的逻辑。2.4G热点
    //(3)加个打印,查看默认的频段值
    Log.d(TAG, "getDefaultApConfiguration generateDefaultBand = " + generateDefaultBand(mContext));
    
    //(4)设置默认5G的一段逻辑,添加prop属性进行判断
    boolean isDefault5G = SystemProperties.getBoolean("persist.sys.mydebug.hotspot_default_5G", true);
    Log.d(TAG, "getDefaultApConfiguration isDefault5G = " + isDefault5G);
    if (isDefault5G) {
    	// (5)判断是否支持5G,设置5G band 和 36 信道值。
        if (ApConfigUtil.isBandSupported(SoftApConfiguration.BAND_5GHZ, mContext)) {
            Log.d(TAG, "getDefaultApConfiguration set band = 5G");
            configBuilder.setChannel(36, SoftApConfiguration.BAND_5GHZ);
        } else {
            Log.d(TAG, "getDefaultApConfiguration set band = 2G");
            configBuilder.setChannel(3, SoftApConfiguration.BAND_2GHZ);
        }
    } else { // (6)如果设置prop属性为 false,还是原来的逻辑
        configBuilder.setBand(generateDefaultBand(mContext));
    }

	//(7)默认名称,AndroidAP_四位随机数
    configBuilder.setSsid(mContext.getResources().getString(
            R.string.wifi_tether_configure_ssid_default) + "_" + getRandomIntForDefaultSsid());
    
    //(8)热点加密形式,默认不支持wpa3,加密类型:WPA2_PSK
    if (ApConfigUtil.isWpa3SaeSupported(mContext)) {
        configBuilder.setPassphrase(generatePassword(),
                SECURITY_TYPE_WPA3_SAE_TRANSITION);
    } else {
        configBuilder.setPassphrase(generatePassword(),
                SECURITY_TYPE_WPA2_PSK);
    }

    //(9)桥接模式,默认不支持
    if (ApConfigUtil.isBridgedModeSupported(mContext)) {
        if (SdkLevel.isAtLeastS()) {
            int[] dual_bands = new int[] {
                    SoftApConfiguration.BAND_2GHZ,
                    SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ};
            configBuilder.setBands(dual_bands);
        }
    }

    // Update default MAC randomization setting to NONE when feature doesn't support it.	//(10)MAC地址随机,默认为true,但这里方法没进
    if (!ApConfigUtil.isApMacRandomizationSupported(mContext)) {
        if (SdkLevel.isAtLeastS()) {
            configBuilder.setMacRandomizationSetting(SoftApConfiguration.RANDOMIZATION_NONE);
        }
    }

    configBuilder.setUserConfiguration(false);
    //(11)根据信息构建 WifiApConfigStore 对象
    return configBuilder.build();
}


//(12)获取默认频段,BAND_TYPES:2G,5G,6G
public static @BandType int generateDefaultBand(Context context) {
    for (int band : SoftApConfiguration.BAND_TYPES) {
        //(13)这里判断首先是否支持2.4G,支持直接返回了,并未进行后续判断。所以默认是2.4G热点!
        if (ApConfigUtil.isBandSupported(band, context)) {
            return band;
        }
    }
    Log.e(TAG, "Invalid overlay configuration! No any band supported on SoftAp");
    return SoftApConfiguration.BAND_2GHZ;
}

}


上面的 getDefaultApConfiguration() 方法只是系统第一次运行会执行到,并且把获取的默认信息保存到本地配置文件,后续打开过后已经存在信息配置文件就不会再调用获取默认配置的方法了,而是从本地保存的配置文件信息里面获取数据,每次手动保存的数据也是会保存到本地配置文件中的。


更多热点信息可以查看 WifiApConfigStore.java具体代码 。


#### 2、保存默认配置文件设置默认5G频段配置


在系统源码某个mk文件添加文件复制代码:



#set default ap config
PRODUCT_COPY_FILES +=
xxx/WifiConfigStoreSoftAp.xml:data/misc/apexdata/com.android.wifi/WifiConfigStoreSoftAp.xml


在源码xxx路径文件 WifiConfigStoreSoftAp.xml,编译到运行系统的对应目录。


##### 热点配置文件完整信息示例:



console:/ # cat data/misc/apexdata/com.android.wifi/WifiConfigStoreSoftAp.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> "AndroidAP_5409" 844qwtdw 82:d0:fe:82:e1:d0 console:/ #

可以根据自己需求对部分信息进行修改。


编译系统后,直接打开热点就是按照上面的配置信息传给底层的;


应用调用了设置热点配置方法,配置信息也是会保存到 WifiConfigStoreSoftAp.xml 文件的,


后续热点打开都是 WifiConfigStoreSoftAp.xml 的配置信息。


下面的是特殊场景,设置特定热点配置信息,


不管本地配置文件和应用怎么设置,最终热点都是以特定的配置打开。


#### 3、代码中强制设置配置信息


不管应用怎么设置,系统实际生效都是特定的配置,


虽然现实中可能这样的场景比较少,但是万一有呢?


所以还是给大家介绍一下。


##### (1)在关键流程设置


###### 热点开启和关闭代码:



ConnectivityManager mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

//开启
mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, true,
mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));

//关闭
mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);


如果需要实现这个就要对Android 热点设置的流程 比较熟悉了,具体在哪个类进行适配可以呢?


###### 热点启动流程



(1)ConnectivityManager.startTethering
(2)TetheringManager.startTethering(request, executor, tetheringCallback)
(3)TetheringService.TetheringConnector.startTethering
(4)Tethering.startTethering(request, listener);
//方法名变化,使用null 对象开启热点
(5)WifiManager.startTetheredHotspot(null /* use existing softap config */)
(6)WifiServiceImpl.startTetheredHotspot(@Nullable SoftApConfiguration softApConfig)
//方法名再变化
(7)ActiveModeWarden.startSoftAp(apModeConfig);
(8)ActiveModeManager.start();
ActiveModeManager manager = mWifiInjector.makeSoftApManager(listener, callback, softApConfig);
listener.setActiveModeManager(manager);
manager.start();
ActiveModeManager是接口类,会调用到SoftApManager.start()
(9)SoftApManager.startSoftAp()
(10)WifiNative.startSoftAp(mApInterfaceName, localConfigBuilder.build(), mSoftApListener)
(11)HostapdHal.addAccessPoint(ifaceName, config, listener::onFailure)
(12)根据硬件版本调用不同的接口实现:addAccessPoint_X_X


从上面流程看热点开启是不需要参数的,后续SoftApManager里面会获取默认参数,综合观察发现WifiNative 前面强制处理最好。


packages\modules\Wifi\service\java\com\android\server\wifi\SoftApManager.java


###### 热点启动关键流程:



//(1)开启wifi的重要过程
//mCurrentSoftApConfiguration 的信息是构造方法从配置文件中获取的
private int startSoftAp() {
    Log.d(getTag(), "startSoftAp: band " + mCurrentSoftApConfiguration.getBand()
            + " iface " + mApInterfaceName + " country " + mCountryCode);
	//(2)这里强制设置 mCurrentSoftApConfiguration 的配置参数
    //强制设置5G,48信道
    boolean isDefault5G_48 = SystemProperties.getBoolean("persist.sys.mydebug.hotspot_default_5G_48", true);
    Log.d(TAG, "getApConfiguration isDefault5G_48 = " + isDefault5G_48);
    if (isDefault5G_48) {
        mCurrentSoftApConfiguration =  new SoftApConfiguration.Builder(mCurrentSoftApConfiguration)
                .setChannel(48, SoftApConfiguration.BAND_5GHZ).build();
    }
    
    int result = setMacAddress();
    if (result != SUCCESS) {
        return result;
    }

。。。
mWifiDiagnostics.startLogging(mApInterfaceName);
mStartTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
//(3)热点开启成功的标志
Log.d(getTag(), "Soft AP is started ");

    return SUCCESS;
}

验证ok,打开热点默认是是5G 频段,48信道。


而且不管默认配置方法怎么设置,配置文件参数写什么,最终都都是以上面的信息开启的热点。


#### (2)在获取配置信息方法强制设置并返回,是否ok?


packages\modules\Wifi\service\java\com\android\server\wifi\WifiApConfigStore.java



public synchronized SoftApConfiguration getApConfiguration() {
    if (mPersistentWifiApConfig == null) {
        /* Use default configuration. */
        Log.d(TAG, "Fallback to use default AP configuration");
        persistConfigAndTriggerBackupManagerProxy(
                updatePersistentRandomizedMacAddress(getDefaultApConfiguration()));
    }
    SoftApConfiguration sanitizedPersistentconfig =
            sanitizePersistentApConfig(mPersistentWifiApConfig);


//强制设置5G,44信道
boolean isDefault5G_44 = SystemProperties.getBoolean(“persist.sys.mydebug.hotspot_default_5G_44”, true);
Log.d(TAG, "getApConfiguration isDefault5G_44 = " + isDefault5G_44);
if (isDefault5G_44) {
return new SoftApConfiguration.Builder(mPersistentWifiApConfig)
.setChannel(44, SoftApConfiguration.BAND_5GHZ).build();
}
return mPersistentWifiApConfig;
}


其实这里修改看起来不保险?


因为设置一次参数后,系统保存的 mSoftApConfiguration 已经被修改了数据,


重新get是否可以获取到这里的固定的配置信息?


但是想想又可以哦。不管新的对象还是旧的对象都是调用这个方法。set啥都没用?


实际测试是ok 的,打开热点默认是是5G 频段,44信道。


而且不管默认配置方法怎么设置,配置文件参数写什么,最终都都是以上面的信息开启的热点。


如果上面第一种和第二种方式都修改呢?


这不是脱裤子放屁,搞事情吗?


其实是以第一种方式为准,因为 SoftApManager 的构造方法调用了getApConfiguration方法,


后续才调用 startSoftAp,最终数据以后面设置的算数。


最后来对比一下第一种和第二种强制设置配置信息的区别:



1、第一种是关键流程设置固定信息,比较靠谱
2、第二种是获取参数配置返回固定信息,但是系统可能多个地方都会调用到,会增加不确定性,需要一定的压测
3、第一种方式的修改后用户获取到的热点配置信息是不对的,用户还是获取配置文件的或者getApConfiguration方法的信息
4、第二种方式的修改后用户获取到的热点配置信息是正确的,是和实际配置的信息是一致的,虽然和保存在本地文件的信息不一定一致


所以要增加可靠性,第一种和第二种方式都修改也是没有问题的,


记得固定信息要一直,上面代码只是示范效果。


### 三、其他


# 文末

**不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊**

小编将自己6年以来的**面试经验和学习笔记**都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。

![](https://img-blog.csdnimg.cn/img_convert/7063eb7ea6f916713852357260c62230.webp?x-oss-process=image/format,png)


其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。


参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF


**不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊**

小编将自己6年以来的**面试经验和学习笔记**都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。

[外链图片转存中...(img-sKzXgpHO-1724472546034)]


其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。


参考docs.qq.com/doc/DSkNLaERkbnFoS0ZF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值