1. Android 10+ WiFi连接新机制解析
在Android 10(API 29)及更高版本中,Google对WiFi连接API进行了重大重构,废弃了传统的WifiManager.addNetwork()方法,引入了全新的WifiNetworkSpecifier机制。这一变化主要基于以下技术背景:
- 隐私保护强化:旧API允许应用直接操作设备保存的所有WiFi配置,存在隐私泄露风险
- 权限模型优化:新机制要求应用明确声明需要连接的特定网络,避免过度权限请求
- 后台限制收紧:配合Android 10的后台限制政策,减少应用在后台随意修改网络配置的行为
核心变化点在于:
- 连接请求现在通过ConnectivityManager发起
- 必须使用NetworkRequest.Builder构建网络请求规范
- 需要明确定义目标网络的SSID、BSSID和安全类型
2. WifiNetworkSpecifier深度解析
2.1 核心构建流程
WifiNetworkSpecifier.Builder是创建网络连接请求的核心类,其典型用法如下:
java复制WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder()
.setSsid("MyWiFi")
.setWpa2Passphrase("password123");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Android 11+可设置BSSID
builder.setBssid(MacAddress.fromString("00:11:22:33:44:55"));
}
WifiNetworkSpecifier specifier = builder.build();
构建参数说明:
setSsid():必须设置,支持字符串或Pattern模式setBssid():可选,Android 11+支持- 安全类型方法:
setWpa2Passphrase():WPA2-PSKsetWpa3Passphrase():WPA3-SAEsetWpa2EnterpriseConfig():企业级认证
2.2 企业网络特殊配置
对于企业网络(EAP),需要额外配置WifiEnterpriseConfig:
java复制WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
enterpriseConfig.setIdentity("username");
enterpriseConfig.setPassword("password");
enterpriseConfig.setCaCertificate(loadCertificate());
WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
.setSsid("CorporateWiFi")
.setWpa2EnterpriseConfig(enterpriseConfig)
.build();
证书加载示例:
java复制private X509Certificate loadCertificate() throws CertificateException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream is = context.getResources().openRawResource(R.raw.ca_cert);
return (X509Certificate) certFactory.generateCertificate(is);
}
3. 完整连接流程实现
3.1 网络请求构建
完整的网络连接请求需要结合ConnectivityManager:
java复制NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) // 可选
.setNetworkSpecifier(specifier)
.build();
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 连接成功
connectivityManager.bindProcessToNetwork(network); // 可选:绑定进程到该网络
}
@Override
public void onUnavailable() {
// 连接失败
}
};
connectivityManager.requestNetwork(request, callback, 30000); // 30秒超时
3.2 封装工具类实现
建议封装为可复用的工具类:
java复制public class WiFiConnector {
private static final String TAG = "WiFiConnector";
private final Context context;
private ConnectivityManager.NetworkCallback currentCallback;
public WiFiConnector(Context context) {
this.context = context.getApplicationContext();
}
public void connectToWifi(String ssid, String password,
WiFiConnectListener listener) {
disconnectCurrent(); // 断开现有连接
WifiNetworkSpecifier specif
