需求:
Android设备开启热点,使Iphone设备连接,自动开启低数据模式
低数据模式:
低数据模式是一种在移动网络或Wi-Fi环境下,通过限制应用程序的数据使用、降低数据传输速率或禁用某些后台操作来减少数据流量消耗的优化模式。
这种模式主要用于节省数据流量费用,特别是在移动网络流量费用昂贵的情况下。低数据模式可以通过限制应用程序后台数据传输、减小图片质量、禁用自动播放视频等方式来降低数据流量消耗。在iOS设备上,如iPhone,低数据模式可以通过设置中的蜂窝网络或Wi-Fi选项开启。开启后,系统会自动减少后台未使用的应用刷新数据,节约流量并减少设备功耗,从而增强续航能力。
此外,低数据模式不仅适用于移动网络,也适用于Wi-Fi网络。在Wi-Fi网络下,开启低数据模式还可以提升续航能力。
综上,低数据模式起源为IOS 13以后的功能,最常见的表现就是在切换wifi为移动数据时候,后台下载会暂停
基于上述需求,我们知道设备在使用移动数据时候,默认会暂停后台的下载,那如果设备能区分出连接的wifi是热点还是路由器散发的wifi即可达到文章开头的需求。
测试发现小米设备和IOS,在wifi扫描列表,热点和路由器散发的wifi是有明显区分的,详见如下,曲别针图标的是热点,连接该wifi,状态栏图标也是显示未曲别针,但是大部分Android ,在这一块无区分
如图,小米设备也可以区分出热点和路由器wifi,并且散发的热点也可以被Iphone设备识别为移动热点,但是我的设备散发的热点,IPhone设备当做一个普通的wifi,仔细看下小米设备在开启热点的时候,有一个设备标识,可设置为移动热点还是默认,测试发现,设置默认的话,该热点IPhone设备也识别不出来。
我们分别设置这两个开关,摘取下小米的日志,观察如下不同
我们分别设置这两个开关,摘取下小米的日志,观察如下不同
vendor_elements值不同,我们再次push出来小米的Settings,反编译大概看下,发现设置为移动热点的时候,确实是DD0A0017F206010103010000
由此可以确定,小米和Iphone,会识别DD0A0017F206010103010000这个标识,为这个则认定为热点,看下小米的wifi连接页面,判断是否有{0, 23, -14, 6, 1, 1, 3, 1}这一串的标识(DD是开头,0A表示长度为10,后面的0017F206010103010000就是数据,转为10进制就是:{0, 23, -14, 6, 1, 1, 3, 1,0,0})
在热点相关的类中搜索VendorElements相关,发现设置接口和解析接口
设置:
//QSSI.13\packages\modules\Wifi\framework\java\android\net\wifi\SoftApConfiguration.java
@NonNull
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public Builder setVendorElements(@NonNull List<ScanResult.InformationElement> vendorElements) {if (!SdkLevel.isAtLeastT()) {throw new UnsupportedOperationException();}for (ScanResult.InformationElement e : vendorElements) {if (e.id != ScanResult.InformationElement.EID_VSA) {throw new IllegalArgumentException("received InformationElement which is not "+ "related to VendorElements. VendorElement block should start with "+ HexEncoding.encodeToString(new byte[]{ (byte) ScanResult.InformationElement.EID_VSA }));}}final HashSet<ScanResult.InformationElement> set = new HashSet<>(vendorElements);if (set.size() < vendorElements.size()) {throw new IllegalArgumentException("vendor elements array contain duplicates. "+ "Please avoid passing duplicated and keep structure clean.");}mVendorElements = new ArrayList<>(vendorElements);return this;
}解析热点配置文件:data/misc/apexdata/com.android.wifi/WifiConfigStoreSoftAp.xml
public static SoftApConfiguration parseFromXml(XmlPullParser in, int outerTagDepth,SettingsMigrationDataHolder settingsMigrationDataHolder)throws XmlPullParserException, IOException {...
case XML_TAG_VENDOR_ELEMENTS:if (SdkLevel.isAtLeastT()) {softApConfigBuilder.setVendorElements(SoftApConfigurationXmlUtil.p