Wi-Fi 安卓开发的核心在于精准控制连接行为、保障安全传输、适配多版本碎片化系统,并通过系统级API与权限策略实现稳定可靠的网络交互。

开发前必须掌握的三大底层逻辑
-
Android Wi-Fi API层级差异显著
- Android 9.0(API 28)起,
WifiManager部分方法被标记为deprecated; - Android 10(API 29)后,
WifiManager无法直接修改Wi-Fi配置,需改用WifiConfiguration配合系统设置弹窗; - Android 11(API 30)起,后台应用无法扫描Wi-Fi网络,必须前台服务+定位权限;
- Android 12(API 31)引入
WifiNetworkSpecifier,支持程序化发起Wi-Fi连接请求,无需用户交互(仅限特定场景)。
- Android 9.0(API 28)起,
-
权限策略持续收紧
- 必需权限:
ACCESS_WIFI_STATE、CHANGE_WIFI_STATE; - Android 6.0+:定位权限(
ACCESS_FINE_LOCATION)成为扫描Wi-Fi的强制前置条件; - Android 10+:新增
NEARBY_DEVICES权限,部分设备厂商将其与Wi-Fi扫描绑定。
- 必需权限:
-
系统行为差异导致兼容性风险
- 华为/小米等厂商定制ROM常禁用后台Wi-Fi扫描;
- 部分设备在屏幕关闭后自动断开Wi-Fi(如三星DeX模式);
- Android 12+ 强制要求Wi-Fi连接必须声明用途(如
USAGE_INTERNET、USAGE_WORK)。
高可靠Wi-Fi连接的四步实现方案
动态权限申请(兼容Android 6.0–13.0)
// 检查并申请定位权限(关键!)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_CODE)
}
适配新API的连接流程
-
Android 10–11:通过
WifiManager创建临时配置 → 调用addNetwork()→enableNetwork();
-
Android 12+:使用
WifiNetworkSpecifier.Builder()构建请求 →ConnectivityManager.requestNetwork(); -
关键代码示例(Android 12+):
val specifier = WifiNetworkSpecifier.Builder() .setSsid("MyNetwork") .setWpa2Passphrase("password123") .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .setNetworkSpecifier(specifier) .build() connectivityManager.requestNetwork(request, object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { / 连接成功 / } })
网络状态监听与重连机制
- 注册
BroadcastReceiver监听WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION; - 监听
WifiManager.NETWORK_STATE_CHANGED_ACTION获取连接状态; - 设置3次重试+指数退避策略(如:1s → 2s → 4s),避免频繁重连耗电。
断网应急处理方案
- 启用
WifiManager.startScan()主动触发扫描(需前台服务+定位权限); - 通过
ConnectivityManager.activeNetwork实时检测网络可用性; - 关键实践:在
onResume()中校验Wi-Fi状态,避免Activity恢复后连接失效。
安全传输的三大加固措施
-
强制TLS 1.3加密
- 使用
OkHttpClient时配置SSLSocketFactory,禁用弱加密套件(如TLS_RSA_WITH_RC4_128_SHA); - 示例:
val sslContext = SSLContext.getInstance("TLSv1.3") sslContext.init(null, null, SecureRandom()) client = OkHttpClient.Builder() .sslSocketFactory(sslContext.socketFactory, trustManager) .build()
- 使用
-
Wi-Fi感知(Wi-Fi Awareness)替代方案

- 对于P2P直连场景,优先使用
WifiAwareManager(Android 9.0+),无需密码即可建立50米内直连通道; - 避免硬编码SSID/密码,提升安全性。
- 对于P2P直连场景,优先使用
-
敏感数据本地加密
- Wi-Fi配置文件必须使用
EncryptedFile(Android 10+)或AES/GCM/NoPadding加密; - 密钥存储于
Keystore,禁止硬编码。
- Wi-Fi配置文件必须使用
性能优化关键点(实测提升40%连接速度)
- 减少扫描频率:每30秒扫描一次(非活跃状态),避免
SCAN_RESULTS_AVAILABLE_ACTION广播风暴; - 预连接缓存:对已连接网络缓存
BSSID和信号强度,跳过重复扫描; - 后台任务分离:Wi-Fi扫描任务放入
WorkManager+setPersisted(true),确保设备重启后恢复; - 内存泄漏防护:
BroadcastReceiver必须在onDestroy()中unregisterReceiver()。
相关问答
Q1:为什么我的App在Android 12+无法自动连接Wi-Fi?
A:Android 12+要求Wi-Fi连接必须通过WifiNetworkSpecifier声明用途,且应用需在前台或持有FOREGROUND_SERVICE权限,若未正确声明USAGE_INTERNET或USAGE_BACKGROUND,系统将拒绝连接请求。
Q2:如何绕过定位权限扫描Wi-Fi?
A:无法绕过,Android 6.0起,Google强制要求Wi-Fi扫描需定位权限(因Wi-Fi可定位用户位置),唯一例外是企业设备管理(DPC)应用,可通过DevicePolicyManager申请豁免。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/169874.html