随着 Android 系统的不断发展,Wi-Fi
连接控制的实现方式也在不断变化。特别是从 Android 10 开始,Google
加强了对用户隐私和安全的保护,使得 Wi-Fi
连接的实现变得更加复杂。本文将详细介绍不同 Android 版本下 Wi-Fi
连接的实现方式及其技术要点。
Android 10 之前版本的 Wi-Fi
连接
在 Android 10(API 29)之前,应用可以直接控制 Wi-Fi
连接,开发者可以通过简单的 API 调用来连接指定 SSID 和密码的 Wi-Fi
热点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private fun connectWifiLegacy (wifiManager: WifiManager , ssid: String , password: String ) { val wifiConfig = WifiConfiguration() wifiConfig.SSID = String.format("\"%s\"" , ssid) wifiConfig.preSharedKey = String.format("\"%s\"" , password) val netId = wifiManager.addNetwork(wifiConfig) if (netId != -1 ) { wifiManager.enableNetwork(netId, true ) Log.d("Wi-Fi" , "Network added with ID: $netId " ) } else { Log.e("Wi-Fi" , "Failed to add network configuration" ) } }
这种方式简单直接,应用可以完全控制 Wi-Fi 的连接和断开。
Android 10 及以上版本的
Wi-Fi 连接
Android 10 成为了 Wi-Fi 连接控制的重要分水岭。从这个版本开始,Google
引入了新的权限模型和 API,使得应用无法直接强制连接 Wi-Fi 网络。
必要权限
在 Android 10 及以上版本中,连接 Wi-Fi
前需要请求以下四个基本权限:
ACCESS_WIFI_STATE - 访问 Wi-Fi 状态信息
CHANGE_WIFI_STATE - 修改 Wi-Fi 状态
ACCESS_NETWORK_STATE - 访问网络状态信息
CHANGE_NETWORK_STATE - 修改网络状态
连接方案
Android 10 提供了两种 Wi-Fi 连接方案:
1.
WifiNetworkSuggestion(建议连接)
WifiNetworkSuggestion
是一种推荐机制,应用向系统提供网络建议,由系统决定何时连接:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private fun connectWifiWithSuggestion (wifiManager: WifiManager , ssid: String , password: String ) { val suggestion = WifiNetworkSuggestion.Builder() .setSsid(ssid) .setWpa2Passphrase(password) .build() val suggestionsList = listOf(suggestion) val status = wifiManager.addNetworkSuggestions(suggestionsList) when (status) { WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS -> { Log.d("Wi-Fi" , "Successfully added network suggestion for $ssid " ) } } }
优点: - 符合 Android 的隐私保护设计理念 -
用户体验更好,用户有更多控制权 -
系统可以根据网络质量和信号强度智能选择
缺点: - 无法保证立即连接 - 连接时机由系统决定 -
可能需要用户手动确认
2.
WifiNetworkSpecifier(强制连接)
WifiNetworkSpecifier 允许应用强制连接到指定网络:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private fun connectWifiWithSpecifier (wifiManager: WifiManager , ssid: String , password: String ) { val specifier = WifiNetworkSpecifier.Builder() .setSsid(ssid) .setWpa2Passphrase(password) .build() val request = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .setNetworkSpecifier(specifier) .build() val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable (network: Network ) { } override fun onUnavailable () { } } val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager connectivityManager.requestNetwork(request, networkCallback) }
优点: - 可以强制连接到指定网络 - 连接控制更精确 -
不依赖系统决策
缺点: - 可能断开当前网络连接 -
用户体验可能较差,因为连接之前会提示用户确认连接的Wifi热点名称,连接过程中还会提示用户连接进度
- 在某些版本中可能需要额外权限
Android 12+ 的额外要求
从 Android 12(API 31)开始,连接 Wi-Fi 还需要额外申请
ACCESS_FINE_LOCATION 权限,因为 Wi-Fi
信息可以用于定位。这个权限需要在运行时请求:
1 2 3 4 5 6 7 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (ContextCompat.checkSelfPermission(this , Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this , arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_CODE) } }
以上过程中合计需要申请的权限在AndroidManifest.xml中的配置脚本如下:
1 2 3 4 5 <uses-permission android:name ="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name ="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name ="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name ="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name ="android.permission.ACCESS_FINE_LOCATION" />
特殊情况下的 WRITE_SETTINGS
权限
在个别 Android 系统或定制 ROM 中,可能还需要
android.permission.WRITE_SETTINGS 权限,用于保存连接 Wi-Fi
的 SSID 和密码。这是一个特殊权限,需要用户在设置中手动授权:
1 2 3 4 5 6 7 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.System.canWrite(this )) { val intent = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) intent.data = Uri.parse("package:$packageName " ) startActivity(intent) } }
总结
Android Wi-Fi 连接控制的演进体现了 Google
对用户隐私和安全保护的重视。开发者需要根据目标 Android
版本选择合适的连接方案,并正确处理权限申请。在实际开发中,建议:
优先使用 WifiNetworkSuggestion 方案,符合现代 Android
设计理念
仅在必要时使用 WifiNetworkSpecifier 强制连接
正确处理各版本的权限要求
提供良好的用户体验,避免强制切换网络影响用户正常使用