前言
双WiFi2.4G与5G频段使用方式与Android S无差异,主要是新增1.3节MIUI 14 菜单指引和 2.7节,适配支持双5G的机型以进行并发连接
一、双WIFI简介
双WiFi顾名思义提供了手机同时连接两个WiFi同时上网的能力,一般手机只能同时连接AP的一个WiFi频段获取 WiFi信号,而支持双WiFi技术的手机可以同时连接AP的两个频段(2.4Ghz或5GHz)获取WiFi信号(可以连接一个AP的两个频段,也可以连接两个AP的不同频段)。
1、双WIFI的优点
- 提升网络稳定性:如果一路链路因为无线参数波动出现网络波动,可以通过另一链路及时将数据包发送出去;
- 提升网络速度:双WiFi提供了两条链路同时加载数据的能力,提升网络速度。
2、目前小米支持双WiFi的已发布机型
小米10、小米10 Pro、小米11、小米Xiaomi 12、小米Xiaomi 13、Redmi K30 5G、Redmi K30 Pro、红米Redmi K40、红米Redmi K50G、小米MIX FOLD等。
3、如何进入双WIFI UI操作界面
MIUI 13
双WiFi UI操作界面可从手机如下操作路径:“设置->WLAN->WLAN助理->智能多网络加速-双WLAN加速”进入。该界面称为副WiFi界面,副WiFi界面的打开和连接与主WiFi除了频段差异外并无区别(当主WiFi连接5Ghz时,副WiFi只能连接2.4Ghz,反之主WiFi连接2.4Ghz的时候,副WiFi只能连接5Ghz)。如下图所示:

MIUI 14
双WiFi UI操作界面可从手机如下操作路径:“设置->WLAN->网络加速->双WLAN加速”进入。

二、双WIFI接入
1、双WIFI接入需求
- 判断当前机型是否支持双WiFi;
- 判断当前双WiFi是否已连接;
- 若未连接,作双WiFi的连接引导;
- 接入双WiFi 网络;
- 判断主副wifi。
2、判断当前机型是否支持双WiFi
private boolean supportDualWifi(Context context) {
String cloudvalue = Settings.System.getString(context.getContentResolver(), "cloud_slave_wifi_support");
if ("off".equals(cloudvalue)) {
return false;
}
boolean support;
try {
support = context.getResources().getBoolean(
context.getResources().getIdentifier("config_slave_wifi_support", "bool", "android.miui"));
} catch (Exception exception) {
return false;
}
return support;
}
3、判断当前双WIFI是否已连接
WiFi的api都属于系统api,有严格的权限校验,第三方应用无法直接调用。miui提供了workround判断方法,当副WiFi连接上了之后,如下参数会设置为对应的副WiFi的ssid,断开时则会清空,可依此判断当前副WiFi是否已连接。
private boolean isSlaveWifiConnected(Context context) {
String slaveWifiSsid = getDualWifiSsid(context);
if (slaveWifiSsid == null || slaveWifiSsid.isEmpty()){
return false;
} else {
return true;
}
}
private String getDualWifiSsid(Context context){
return Settings.System.getString(context.getContentResolver(), "slave_wifi_ssid");
}
4、若副WiFi未连接,则引导用户至副WiFi界面进行连接
判断当前副WiFi是否已连接,若未连接跳转到系统副WiFi界面引导用户连接,返回到当前界面则再次校验,校验成功后进行副WiFi网络操作。
if (!isSlaveWifiConnected(getApplicationContext())){
//TODO Provide Dual Wifi Ui guidance and reCheck
Intent intent = new Intent("android.settings.DUAL_WIFI.WIFI_SETTINGS");
startActivity(intent);
return;
}
5、接入双WiFi网络part 1/2
初始化网络回调NetworkCallback
ConnectivityManager.NetworkCallback networkCallbackFor24GHZ =
new ConnectivityManager.NetworkCallback() {
public void onAvailable(Network network) {
Log.d(TAG, "24GHZ network is " + network);
Socket skS;
try {
InetAddress[] inetAddress = network.getAllByName("www.mi.com");
for (InetAddress ia : inetAddress) {
Log.d(TAG, "24GHZ Network available: " + ia);
}
skS = network.getSocketFactory().createSocket("www.mi.com", 80);
} catch (IOException e) {
e.printStackTrace();
return;
}
Log.d(TAG, "24GHZ skS = " + skS.toString());
Log.d(TAG, "24GHZ skS = " + getNetworkWifiInfo(network));
Log.d(TAG, "24GHZ skS isprimary = " + isPrimaryWifi(getNetworkWifiInfo(network)));
}
};
ConnectivityManager.NetworkCallback networkCallbackFor5GHZ =
new ConnectivityManager.NetworkCallback() {
public void onAvailable(Network network) {
Log.d(TAG, "5GHZ network is " + network);
Socket skS;
try {
InetAddress[] inetAddress = network.getAllByName("www.mi.com");
for (InetAddress ia : inetAddress) {
Log.d(TAG, "5GHZ Network available: " + ia);
}
skS = network.getSocketFactory().createSocket("www.mi.com", 80);
} catch (IOException e) {
e.printStackTrace();
return;
}
Log.d(TAG, "5GHZ skS = " + skS.toString());
Log.d(TAG, "5GHZ skS = " + getNetworkWifiInfo(network));
Log.d(TAG, "5GHZ skS isprimary = " + isPrimaryWifi(getNetworkWifiInfo(network)));
}
};
6、接入双WiFi网络part 2/2
请求两路band,即双wifi的2.4G & 5G 频段对应的网络
private void requestDualBand() {
requestSpecificBandWifi(true);
requestSpecificBandWifi(false);
}
private void requestSpecificBandWifi(boolean is24GHZ) {
WifiNetworkSpecifier.Builder specifierBuilder =
new WifiNetworkSpecifier.Builder();
specifierBuilder.setBand(is24GHZ ? ScanResult.WIFI_BAND_24_GHZ : ScanResult.WIFI_BAND_5_GHZ);
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI)
.removeCapability(NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifierBuilder.build())
.build();
mCm.requestNetwork(request, is24GHZ ? networkCallbackFor24GHZ : networkCallbackFor5GHZ);
}
7、双5G适配
//判断是否支持双5G
private boolean supportHbsDualWifi(Context context) {
String cloudvalue = Settings.System.getString(context.getContentResolver(), "cloud_wifi_hbs_support");
if ("off".equals(cloudvalue)) {
return false;
}
boolean support;
try {
support = context.getResources().getBoolean(
context.getResources().getIdentifier("config_wifi_hbs_support", "bool", "android.miui"));
} catch (Exception exception) {
Log.d(TAG, "supportDbsDualWifi " + exception);
return false;
}
return support;
}
若支持,请求第二路5G wifi(主wifi 5G band同2.6节请求ScanResult.WIFI_BAND_5_GHZ 即可)
private static final int WIFI_BAND_5_GHZ_HBS = 1 << 8 | ScanResult.WIFI_BAND_5_GHZ;
private void requestSpecificHbsBandWifi() {
WifiNetworkSpecifier.Builder specifierBuilder =
new WifiNetworkSpecifier.Builder();
specifierBuilder.setBand(WIFI_BAND_5_GHZ_HBS);
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI)
.removeCapability(NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifierBuilder.build())
.build();
mCm.requestNetwork(request, networkCallbackForHbs5GHZ);
}
ConnectivityManager.NetworkCallback networkCallbackForHbs5GHZ =
new ConnectivityManager.NetworkCallback() {
public void onAvailable(Network network) {
Log.d(TAG, "5GHZ HBS network is " + network);
Socket skS;
try {
InetAddress[] inetAddress = network.getAllByName("www.mi.com");
for (InetAddress ia : inetAddress) {
Log.d(TAG, "5GHZ HBS Network available: " + ia);
}
skS = network.getSocketFactory().createSocket("www.mi.com", 80);
} catch (IOException e) {
e.printStackTrace();
return;
}
Log.d(TAG, "5GHZ HBS skS = " + skS.toString());
}
};
8、判断主副wifi
判断请求的网络是主wifi还是副wifi,若返回true,则是主wifi,否则是副wifi
private boolean isPrimaryWifi(WifiInfo wifiInfo) {
if (wifiInfo != null && wifiInfo.getFrequency() != -1//means the wifi is connected
&& mWifiManager.getConnectionInfo().getFrequency() == (wifiInfo.getFrequency())) {
return true;
} else {
return false;
}
}
三、联系我们
如遇技术问题,请联系zhujiatai@xiaomi.com