WiFi 作为移动设备最核心的网络连接方式,在 Android 系统中占据着至关重要的地位。从简单的网络连接管理到复杂的 P2P 通信,从传统的 2.4GHz 频段到最新的 6GHz 频谱,Android WiFi 框架经历了十余代版本的演进,形成了一套完整而复杂的 API 体系。本文将系统梳理 Android WiFi 开发的核心技术,从基础的状态监控到高级的 WiFi 6 优化,结合 Android 14 的最新特性,为开发者提供从入门到精通的实战指南。
一、Android WiFi 框架核心组件
Android 的 WiFi 功能基于 Linux 内核的cfg80211和mac80211驱动框架,通过 Java 层的 API 向应用开发者开放能力。理解这套框架的核心组件是进行 WiFi 开发的基础。
1.1 核心系统服务与类
Android WiFi 框架的核心组件位于android.net.wifi包中,主要包括:
- WifiManager:最核心的服务类,提供 WiFi 开关控制、扫描、连接管理等基础功能,通过Context.getSystemService(Context.WIFI_SERVICE)获取实例。
- WifiInfo:封装当前连接的 WiFi 网络信息,如 SSID、BSSID、信号强度等。
- ScanResult:表示扫描到的 WiFi 网络热点信息,包含 SSID、BSSID、加密方式、信道、信号强度等。
- WifiConfiguration:用于配置 WiFi 网络连接参数,如 SSID、密码、加密类型等,在 Android 10 后逐渐被WifiNetworkSpecifier替代。
- WifiP2pManager:管理 WiFi 直连(P2P)功能,支持设备发现、连接建立和数据传输。
- NetworkRequest与ConnectivityManager:用于高级网络请求和连接管理,配合 WiFi 使用以实现更灵活的网络选择策略。
这些组件之间的关系可以用如下模型表示:WifiManager作为核心服务,通过与底层驱动交互完成实际的 WiFi 操作,WifiInfo和ScanResult提供数据模型,WifiConfiguration和WifiNetworkSpecifier负责配置管理,而ConnectivityManager则从系统层面协调各种网络类型的切换与优先级。
1.2 权限体系演变
Android 对 WiFi 相关权限的管理经历了多次调整,特别是在隐私保护强化的背景下,权限要求变得更加严格:
Android 版本 | 核心权限变化 | 位置权限要求 | 后台扫描限制 |
6.0 (API 23) | 引入危险权限ACCESS_COARSE_LOCATION | 扫描需要位置权限 | 无限制 |
10 (API 29) | 新增ACCESS_FINE_LOCATION要求 | 必须获取精确定位权限 | 后台扫描频率限制 |
12 (API 31) | 新增NEARBY_WIFI_DEVICES权限 | 部分操作可替代位置权限 | 更严格的频率控制 |
13 (API 33) | 细化NEARBY_WIFI_DEVICES权限范围 | 明确区分位置相关操作 | 扫描结果过滤非已保存网络 |
在 Android 12 及以上版本中,对于仅需要发现附近 WiFi 设备而不需要获取位置信息的场景(如 WiFi P2P),可以使用ACCESS_WIFI_STATE和NEARBY_WIFI_DEVICES权限替代位置权限,但需要在 Manifest 中声明并动态请求。
<!-- Android 12+ WiFi基础权限配置 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" /> <!-- 仅在Android 12以下需要 -->
动态请求权限的代码示例:
// 检查并请求WiFi相关权限
fun checkWifiPermissions(context: Context) {
val permissions = mutableListOf<String>()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
permissions.add(Manifest.permission.NEARBY_WIFI_DEVICES)
} else {
permissions.add(Manifest.permission.ACCESS_FINE_LOCATION)
}
permissions.add(Manifest.permission.ACCESS_WIFI_STATE)
permissions.add(Manifest.permission.CHANGE_WIFI_STATE)
// 检查未授予的权限
val ungranted = permissions.filter {
ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED
}
if (ungranted.isNotEmpty()) {
ActivityCompat.requestPermissions(
context as Activity,
ungranted.toTypedArray(),
WIFI_PERMISSION_REQUEST_CODE
)
}
}
二、WiFi 基础操作开发实战
2.1 WiFi 状态监控与控制
开发 WiFi 相关功能的第一步是掌握 WiFi 状态的监控与基本控制。WifiManager提供了完整的 API 来管理 WiFi 开关状态:
class WifiController(context: Context) {
private val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
// 检查WiFi是否开启
fun isWifiEnabled(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
wifiManager.isWifiEnabled
} else {
@Suppress("DEPRECATION")
wifiManager.isWifiEnabled
}
}
// 切换WiFi开关状态(Android 10以上需要位置权限)
fun toggleWifi(enable: Boolean): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android 10+使用startActivityForResult方式
return try {
val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
context.startActivity(intent)
true
} catch (e: Exception) {
false
}
} else {
@Suppress("DEPRECATION")
return wifiManager.setWifiEnabled(enable)
}
}
// 注册WiFi状态变化监听
fun registerWifiStateListener(owner: Context, listener: (Int) -> Unit) {
val intentFilter = IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)
owner.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN)
listener(state)
}
}, intentFilter)
}
}
需要注意的是,从 Android 10(API 29)开始,WifiManager.setWifiEnabled()方法被标记为过时,应用不能再直接通过代码开关 WiFi,必须引导用户到系统设置页面进行操作,这是出于用户隐私和电量优化的考虑。
2.2 网络扫描与结果解析
WiFi 扫描是获取周围网络信息的基础功能,但在不同 Android 版本中实现方式有所不同:
class WifiScanner(context: Context) {
private val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
private val scanResults = mutableListOf<ScanResult>()
// 开始WiFi扫描(需要权限)
fun startScan(context: Context, callback: (List<ScanResult>) -> Unit) {
// 检查权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
ContextCompat.checkSelfPermission(context, Manifest.permission.NEARBY_WIFI_DEVICES)
!= PackageManager.PERMISSION_GRANTED) {
return
}
// 注册扫描结果广播
val scanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
if (success) {
@Suppress("DEPRECATION")
scanResults.clear()
scanResults.addAll(wifiManager.scanResults)
callback(processScanResults(scanResults))
}
context.unregisterReceiver(this)
}
}
val intentFilter = IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(scanReceiver, intentFilter)
// 发起扫描
val started = wifiManager.startScan()
if (!started) {
// 扫描发起失败,可能是频率限制
context.unregisterReceiver(scanReceiver)
callback(emptyList())
}
}
// 处理扫描结果,提取有用信息
private fun processScanResults(results: List<ScanResult>): List<WifiNetworkInfo> {
return results.mapNotNull { result ->
// Android 13+对未保存网络隐藏SSID
val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
result.isHidden && !result.isSaved) {
null // 未保存的隐藏网络不显示
} else {
result.ssid.removeSurrounding("\"") // 去除SSID前后的引号
}
ssid?.let {
WifiNetworkInfo(
ssid = it,
bssid = result.bssid,
signalLevel = calculateSignalLevel(result.level),
frequency = result.frequency,
channel = getChannelFromFrequency(result.frequency),
security = getSecurityType(result.capabilities),
is5GHz = result.frequency in 5000..6000,
is6GHz = result.frequency in 5925..7125 // WiFi 6E频段
)
}
}.distinctBy { it.ssid + it.bssid } // 去重相同SSID和BSSID的网络
}
// 计算信号强度等级(0-4)
private fun calculateSignalLevel(rssi: Int): Int {
return WifiManager.calculateSignalLevel(rssi, 5)
}
// 从频率获取信道
private fun getChannelFromFrequency(freq: Int): Int {
return when (freq) {
in 2412..2484 -> (freq - 2407) / 5
in 5170..5825 -> (freq - 5170) / 20 + 36
in 5925..7125 -> (freq - 5925) / 20 + 149
else -> 0
}
}
// 解析加密类型
private fun getSecurityType(capabilities: String): String {
return when {
capabilities.contains("WPA3") -> "WPA3"
capabilities.contains("WPA2") -> "WPA2"
capabilities.contains("WPA") -> "WPA"
capabilities.contains("WEP") -> "WEP"
else -> "OPEN"
}
}
// 数据类:WiFi网络信息
data class WifiNetworkInfo(
val ssid: String,
val bssid: String,
val signalLevel: Int,
val frequency: Int,
val channel: Int,
val security: String,
val is5GHz: Boolean,
val is6GHz: Boolean
)
}
Android 13(API 33)对 WiFi 扫描结果进行了重要调整:对于未保存的网络,系统会隐藏其 SSID(返回空字符串),并且ScanResult.ssid不再包含前后的引号。这些变化需要开发者在处理扫描结果时特别注意,避免解析错误。
2.3 连接 WiFi 网络
连接 WiFi 网络的方法在不同 Android 版本中有显著差异,从传统的WifiConfiguration到现代的WifiNetworkSpecifier,API 设计更加注重安全性和用户控制:
传统连接方式(Android 9 及以下)
@Deprecated("Use WifiNetworkSpecifier for Android 10+")
fun connectToWifiLegacy(ssid: String, password: String): Boolean {
val config = WifiConfiguration().apply {
this.SSID = "\"$ssid\"" // 需要包含引号
when (getSecurityType(password)) {
"WPA2", "WPA3" -> {
preSharedKey = "\"$password\""
allowedProtocols.set(WifiConfiguration.Protocol.RSN)
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
}
"WEP" -> {
wepKeys[0] = "\"$password\""
wepTxKeyIndex = 0
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
}
else -> { // 开放网络
allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
}
}
}
// 添加网络配置
val networkId = wifiManager.addNetwork(config)
if (networkId == -1) return false
// 保存并连接
wifiManager.saveConfiguration()
return wifiManager.enableNetwork(networkId, true)
}
现代连接方式(Android 10 及以上)
fun connectToWifiModern(context: Context, ssid: String, password: String) {
val securityType = getSecurityType(password)
val networkSpecifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.apply {
when (securityType) {
"WPA2", "WPA3" -> setWpa2Passphrase(password)
"WEP" -> setWepKeys(arrayOf(password))
// 开放网络不需要密码
}
}
.build()
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(networkSpecifier)
.build()
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
// 网络可用,可绑定该网络进行通信
connectivityManager.bindProcessToNetwork(network)
}
override fun onUnavailable() {
super.onUnavailable()
// 连接失败
}
}
connectivityManager.requestNetwork(networkRequest, networkCallback)
// 记得在适当的时候调用unregisterNetworkCallback
}
现代连接方式通过NetworkRequest和WifiNetworkSpecifier实现,这种方式不会将网络添加到系统保存的网络列表中,适用于临时连接场景,并且更好地遵循了 Android 的权限模型。
三、高级 WiFi 功能开发
3.1 WiFi P2P(点对点通信)
WiFi P2P 允许设备在没有接入点的情况下直接通信,适用于文件传输、 multiplayer 游戏等场景。实现 WiFi P2P 需要使用WifiP2pManager:
class WifiP2pManager(context: Context) {
private val manager = context.getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager
private val channel = manager.initialize(context, context.mainLooper, null)
private val peers = mutableListOf<WifiP2pDevice>()
// 发现附近的P2P设备
fun discoverPeers(listener: (List<WifiP2pDevice>) -> Unit) {
val peerListListener = WifiP2pManager.PeerListListener { peerList ->
peers.clear()
peers.addAll(peerList.deviceList)
listener(peers)
}
manager.discoverPeers(channel, object : WifiP2pManager.ActionListener {
override fun onSuccess() { /* 发现开始 */ }
override fun onFailure(reason: Int) { /* 发现失败 */ }
})
// 注册广播接收器监听设备发现结果
val intentFilter = IntentFilter().apply {
addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)
addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)
addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)
}
context.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> {
manager.requestPeers(channel, peerListListener)
}
// 处理其他P2P相关事件
}
}
}, intentFilter)
}
// 连接到指定设备
fun connectToDevice(device: WifiP2pDevice, listener: (Boolean) -> Unit) {
val config = WifiP2pConfig().apply {
deviceAddress = device.deviceAddress
wps.setup = WifiP2pConfig.WpsInfo.PBC // 使用按钮配置方式
}
manager.connect(channel, config, object : WifiP2pManager.ActionListener {
override fun onSuccess() { /* 连接请求已发送 */ }
override fun onFailure(reason: Int) {
listener(false)
}
})
}
// 建立数据连接(需要使用Socket)
fun setupDataConnection() {
// 作为服务端监听连接
Executors.newSingleThreadExecutor().execute {
val serverSocket = ServerSocket(8888)
val clientSocket = serverSocket.accept()
// 通过clientSocket进行数据读写
}
}
}
WiFi P2P 通信的完整实现还需要处理连接状态变化、IP 地址分配等事件,并通过 Socket 进行实际的数据传输。在 Android 12 及以上版本,使用 WiFi P2P 需要NEARBY_WIFI_DEVICES权限,并声明neverForLocation标志以避免位置权限要求。
3.2 WiFi Aware(邻居感知网络)
WiFi Aware(也称为 Neighbor Awareness Networking,NAN)是一种低功耗的设备发现和通信技术,相比 WiFi P2P 更适合近距离(约 50 米)的设备发现。它允许设备在不连接到网络的情况下发现附近的其他设备并交换数据:
class WifiAwareManager(context: Context) {
private val awareManager = context.getSystemService(Context.WIFI_AWARE_SERVICE) as WifiAwareManager
private var session: WifiAwareSession? = null
// 初始化WiFi Aware会话
fun initializeSession(callback: () -> Unit) {
awareManager.attach(object : WifiAwareManager.AttachCallback() {
override fun onAttached(s: WifiAwareSession) {
session = s
callback()
}
override fun onAttachFailed() { /* 初始化失败 */ }
}, Handler(Looper.getMainLooper()))
}
// 发布服务(让其他设备发现)
fun publishService(serviceName: String) {
session?.let { session ->
val config = PublishConfig.Builder()
.setServiceName(serviceName)
.setType("myapp.serviceType")
.setRetryCount(3)
.build()
session.publish(config, object : WifiAwareSession.PublishCallback() {
override fun onPublished(publication: WifiAwarePublication) {
// 服务发布成功,可通过publication获取发布信息
}
}, Handler(Looper.getMainLooper()))
}
}
// 发现附近的服务
fun discoverServices(serviceType: String, listener: (List<DiscoveredServiceInfo>) -> Unit) {
session?.let { session ->
val config = DiscoverConfig.Builder()
.setServiceType(serviceType)
.build()
session.discover(config, object : WifiAwareSession.DiscoverCallback() {
override fun onServiceDiscovered(info: DiscoveredServiceInfo) {
// 发现服务,处理服务信息
listener(listOf(info))
}
}, Handler(Looper.getMainLooper()))
}
}
}
WiFi Aware 适用于需要低延迟、低功耗设备发现的场景,如商场导购、社交应用的 "附近的人" 等功能。它的发现范围通常比蓝牙更远,同时比 WiFi P2P 更节能。
3.3 网络感知与切换
Android 提供了灵活的网络感知机制,允许应用根据网络质量和类型调整行为。结合ConnectivityManager和NetworkCallback可以实现高级网络管理:
class NetworkMonitor(context: Context) {
private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// 监听WiFi网络质量变化
fun monitorWifiQuality(listener: (Int) -> Unit) {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, object : ConnectivityManager.NetworkCallback() {
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
super.onLinkPropertiesChanged(network, linkProperties)
// 获取链路属性,如IP地址、DNS等
}
override fun onNetworkCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
super.onNetworkCapabilitiesChanged(network, networkCapabilities)
// 获取网络能力,如带宽估计
val downlinkBandwidth = networkCapabilities.linkDownstreamBandwidthKbps
val quality = when (downlinkBandwidth) {
in 0..1000 -> 1 // 差
in 1001..10000 -> 2 // 中
else -> 3 // 好
}
listener(quality)
}
})
}
// 选择最佳网络(如优先5GHz WiFi)
fun requestBestNetwork() {
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(
WifiNetworkSpecifier.Builder()
.setBand(WifiNetworkSpecifier.BAND_5_GHZ) // 优先5GHz频段
.build()
)
.build()
connectivityManager.requestNetwork(networkRequest, object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
// 绑定到该网络
connectivityManager.bindProcessToNetwork(network)
}
})
}
}
通过网络质量监控,应用可以实现智能行为调整,例如在网络质量差时降低视频分辨率,在优质 WiFi 网络下自动备份数据等。
四、WiFi 6 与性能优化
4.1 WiFi 6 核心特性与 Android 支持
WiFi 6(802.11ax)是最新的 WiFi 标准,相比前代(WiFi 5)带来了显著的性能提升,主要特性包括:
- OFDMA:正交频分多址,允许同时与多个设备通信,提高密集环境下的吞吐量。
- 1024-QAM:更高的调制方式,单流速率提升至 1.2Gbps。
- MU-MIMO:多用户多输入多输出,支持更多设备同时通信。
- BSS Coloring:通过 "着色" 区分不同接入点,减少相邻网络干扰。
- Target Wake Time (TWT):设备可以协商唤醒时间,显著降低功耗。
Android 从 Android 10(API 29)开始支持 WiFi 6,通过WifiManager和NetworkCapabilities可以获取 WiFi 6 相关信息:
// 检查设备是否支持WiFi 6
fun supportsWifi6(context: Context): Boolean {
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
wifiManager.isWifi6Supported
} else {
// 低版本通过扫描结果推断
val scanResults = wifiManager.scanResults
scanResults.any { it.frequency in 5925..7125 } // 6GHz频段通常支持WiFi 6
}
}
// 检查当前连接是否使用WiFi 6
fun isUsingWifi6(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = connectivityManager.activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
capabilities.isWifi6Supported
} else {
// 间接判断:检查是否支持160MHz信道或HE(High Efficiency)
val wifiInfo = (context.getSystemService(Context.WIFI_SERVICE) as WifiManager).connectionInfo
wifiInfo.channelWidth == 160 // 160MHz通常是WiFi 6特性
}
}
4.2 针对 WiFi 6 的应用优化策略
虽然 WiFi 6 主要是底层技术升级,但应用开发者可以通过以下策略充分利用其特性:
1.批量数据传输优化:
利用 WiFi 6 的高吞吐量特性,在后台批量传输数据时使用更大的缓冲区,减少连接建立次数。
// 优化的文件上传方法(适用于WiFi 6)
fun uploadFilesOptimized(files: List<File>, callback: (Boolean) -> Unit) {
if (isUsingWifi6(context)) {
// WiFi 6环境下使用更大的并发和缓冲区
val executor = Executors.newFixedThreadPool(4) // 增加并发数
val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.callTimeout(120, TimeUnit.SECONDS)
.build()
// 批量上传
val requests = files.map { file ->
Request.Builder()
.url(UPLOAD_URL)
.post(RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build()
}
// 执行批量请求
val futures = requests.map { client.newCall(it).enqueueAsync(executor) }
// 等待所有请求完成
futures.forEach { it.get() }
callback(true)
} else {
// 传统网络环境下的上传策略
uploadFilesLegacy(files, callback)
}
}
2.利用 TWT 降低功耗:
在物联网设备或后台应用中,配合系统的 TWT 机制减少唤醒次数,延长电池寿命。
3.动态调整视频流质量:
在 WiFi 6 环境下提供更高分辨率和帧率的视频流,提升用户体验。
4.多连接管理:
对于支持双 WiFi(2.4GHz+5GHz 同时连接)的设备,合理分配不同类型的流量,将大带宽需求的任务分配到 5GHz/6GHz 频段。
4.3 常见 WiFi 性能问题及解决方案
开发 WiFi 相关应用时,经常会遇到各种性能问题,以下是一些常见问题及优化方案:
问题 | 原因 | 解决方案 |
连接不稳定 | 信号弱、信道干扰、AP 负载过高 | 1. 监控信号强度,低于阈值时提醒用户2. 优先连接 5GHz 频段(干扰较少)3. 实现快速重连机制 |
扫描耗电 | 频繁扫描导致 WiFi 芯片持续工作 | 1. 减少扫描频率,使用指数退避策略2. 利用系统扫描结果缓存3. 在充电时执行批量扫描 |
后台传输受限 | Android 后台网络限制 | 1. 使用 WorkManager 在合适时机传输2. 重要数据使用 ForegroundService3. 利用 WiFi 感知预测网络可用时间 |
网络切换卡顿 | 从 WiFi 切换到移动网络时的连接中断 | 1. 使用 NetworkCallback 提前感知切换2. 实现请求重试机制3. 对关键数据使用缓存 |
五、实战案例:WiFi 分析工具
结合前面介绍的各种技术,我们可以开发一个功能完整的 WiFi 分析工具,具备网络扫描、信号强度监控、信道分析等功能。以下是核心功能的实现:
class WifiAnalyzer(context: Context) {
private val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
private val scanner = WifiScanner(context)
private val networkMonitor = NetworkMonitor(context)
// 分析当前信道拥堵情况
fun analyzeChannels(callback: (List<ChannelAnalysis>) -> Unit) {
scanner.startScan(context) { results ->
// 按信道分组统计
val channelStats = results.groupBy { it.channel }
.mapValues { entry ->
ChannelAnalysis(
channel = entry.key,
networkCount = entry.value.size,
signalLevels = entry.value.map { it.signalLevel },
is5GHz = entry.value.firstOrNull()?.is5GHz == true,
is6GHz = entry.value.firstOrNull()?.is6GHz == true,
congestion = calculateCongestion(entry.value)
)
}
.values
.sortedBy { it.channel }
callback(channelStats)
}
}
// 计算信道拥堵程度(0-100)
private fun calculateCongestion(networks: List<WifiScanner.WifiNetworkInfo>): Int {
val signalSum = networks.sumOf { it.signalLevel }
val avgSignal = signalSum / networks.size
// 网络数量越多、信号越强,拥堵程度越高
return ((networks.size * 5) + avgSignal * 2).coerceAtMost(100)
}
// 推荐最佳信道
fun recommendBestChannel(): Int {
var bestChannel = 6 // 默认2.4GHz信道
var minCongestion = 100
analyzeChannels { channels ->
// 优先推荐5GHz或6GHz信道(干扰较少)
val candidateChannels = channels.filter { it.is5GHz || it.is6GHz }
.ifEmpty { channels } // 如果没有则退回到所有信道
// 选择拥堵程度最低的信道
candidateChannels.forEach {
if (it.congestion < minCongestion) {
minCongestion = it.congestion
bestChannel = it.channel
}
}
}
return bestChannel
}
// 数据类:信道分析结果
data class ChannelAnalysis(
val channel: Int,
val networkCount: Int,
val signalLevels: List<Int>,
val is5GHz: Boolean,
val is6GHz: Boolean,
val congestion: Int // 0-100
)
}
这个 WiFi 分析工具可以帮助用户找到最佳的 WiFi 信道,优化路由器设置,从而提升网络质量。实际应用中还可以添加历史数据记录、网络速度测试、AP 厂商识别等功能。
六、未来趋势
随着 WiFi 6E(支持 6GHz 频段)和 WiFi 7(802.11be)的逐步普及,Android WiFi 开发将迎来更多新特性:
- 6GHz 频段支持:Android 12 及以上已经支持 6GHz 频段,开发者需要适应更宽的信道(160MHz)和更多的可用信道数量。
- 多链路聚合:WiFi 7 支持多链路操作,允许设备同时使用 2.4GHz、5GHz 和 6GHz 频段,开发者需要考虑如何在应用层利用这一特性实现更高吞吐量。
- 增强型位置服务:结合 WiFi RTT(Round-Trip Time)进行室内定位的 API 将更加成熟,定位精度可达 1 米以内。
- 更智能的网络选择:系统将提供更详细的网络质量预测,帮助应用做出更明智的网络选择决策。
- 隐私保护强化:未来版本可能会进一步限制对 WiFi 扫描结果的访问,要求更明确的用户授权,开发者需要提前适应这些变化。
作为开发者,应该持续关注 Android WiFi API 的更新,特别是android.net.wifi和android.net包中的新类和方法,及时调整应用以适应新的系统特性和权限要求。
结语
Android WiFi 开发涉及从基础状态管理到高级 P2P 通信的广泛领域,既需要掌握传统的WifiManager API,也需要熟悉现代的NetworkRequest和WifiNetworkSpecifier等组件。随着 WiFi 6/6E 的普及和 Android 版本的迭代,权限模型和 API 设计不断演进,开发者需要在功能实现和用户隐私保护之间找到平衡。
本文涵盖的技术点为开发者提供了全面的参考框架,实际开发中还需要结合具体应用场景进行调整和优化。通过合理利用 Android 提供的 WiFi 能力,开发者可以构建出连接更稳定、性能更优异、用户体验更佳的网络应用。