如何通过代码配置带额外安全层设备的已记录WiFi网络?
实现代码
以下是针对不同Android版本的WiFi Enterprise配置实现:
if (!wifiManager.isWifiEnabled) { wifiManager.isWifiEnabled = true } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { // only for gingerbread and newer versions val wifiEnterpriseConfig = WifiEnterpriseConfig() val wifiConfiguration = WifiConfiguration() wifiConfiguration.status = WifiConfiguration.Status.ENABLED wifiEnterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP wifiEnterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.MSCHAPV2 wifiEnterpriseConfig.caCertificate = null wifiEnterpriseConfig.anonymousIdentity = null wifiEnterpriseConfig.identity = "\"" + BuildConfig.WIFI_USER + "\"" wifiEnterpriseConfig.password = "\"" + BuildConfig.WIFI_PASS + "\"" wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP) wifiConfiguration.enterpriseConfig = wifiEnterpriseConfig wifiConfiguration.SSID = "\"" + BuildConfig.WIFI_SSID + "\"" wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X) wifiConfiguration.preSharedKey = "\"" + BuildConfig.WIFI_PASS + "\"" wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP) wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP) wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP) wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP) wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN) wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA) var ssid = wifiManager.addNetwork( wifiConfiguration ) Log.d("es.paytef.wificepsamanager", "Añade la configuración: $wifiConfiguration") Log.d( "es.paytef.wificepsamanager", "Tras añadir a la config: ${wifiManager.configuredNetworks}" ) //Enable all the interface wifiManager.configuredNetworks.map { it.status = WifiConfiguration.Status.ENABLED Log.d( "es.paytef.wificepsamanager", "Habilita el status de: ssid:${it.SSID} status: ${it.status}" ) } wifiManager.disconnect() Log.d("es.paytef.wificepsamanager", "Habilita el wifi: $ssid") wifiManager.enableNetwork(ssid, true) // this initiates the connection Log.d("es.paytef.wificepsamanager", "Conecta el wifi: ssid:$ssid ") wifiManager.reconnect() }else { val config = WifiConfiguration() config.SSID = BuildConfig.WIFI_SSID config.priority = 1 config.status = WifiConfiguration.Status.ENABLED val enterpriseConfig = WifiEnterpriseConfig() config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X) config.allowedProtocols.set(WifiConfiguration.Protocol.RSN) config.allowedProtocols.set(WifiConfiguration.Protocol.WPA) config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP) config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP) config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP) config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP) enterpriseConfig.identity = BuildConfig.WIFI_USER enterpriseConfig.password = BuildConfig.WIFI_PASS enterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP enterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.MSCHAPV2 config.enterpriseConfig = enterpriseConfig val id = wifiManager.addNetwork(config) Log.d("es.paytef.wificepsa", "# addNetwork returned $id") wifiManager.configuredNetworks.map { it.status = WifiConfiguration.Status.ENABLED } wifiManager.enableNetwork(id, true) }
权限配置
当前AndroidManifest中声明的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
问题背景
已解决Android 7设备的配置兼容问题,但在IM30这类带有额外安全层、限制修改已存网络的设备上,现有代码无法生效。询问是否可通过常规代码配置这类受保护的网络,或是否需要使用hack脚本。
针对定制安全设备的解决方案建议
- 核心原因:IM30这类工业/定制设备的额外安全层是厂商基于Android系统添加的权限拦截机制,普通第三方APP的Android API调用会被系统拒绝。
常规代码方案尝试方向
申请系统级权限:
部分厂商要求APP拥有android.permission.WRITE_SECURE_SETTINGS权限才能修改WiFi配置,该权限无法通过常规运行时权限申请,需通过ADB命令授予:adb shell pm grant 你的应用包名 android.permission.WRITE_SECURE_SETTINGS授予后可尝试结合
Settings.Secure相关API辅助配置,但适配性取决于厂商限制。修正WiFi配置参数:
代码中针对Android O及以上版本设置了allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP),但PEAP+MSCHAPV2认证通常不需要LEAP算法,该参数可能导致定制设备拒绝配置,建议移除该设置后测试。排查配置添加状态:
调用wifiManager.addNetwork后,若返回-1说明配置被系统拒绝,可通过logcat捕获系统日志,查找具体拒绝原因(如权限不足、参数非法等)。
Hack脚本方案可行性
如果厂商安全层仅拦截Android API,可尝试root权限下使用wpa_cli命令直接配置WiFi,这是绕过系统API限制的有效方式,示例命令如下:
# 连接wpa_supplicant并添加网络 wpa_cli -i wlan0 add_network # 设置SSID wpa_cli -i wlan0 set_network 0 ssid "\"你的WiFi名称\"" # 设置认证方式 wpa_cli -i wlan0 set_network 0 key_mgmt WPA-EAP IEEE8021X # 设置EAP方法 wpa_cli -i wlan0 set_network 0 eap PEAP # 设置Phase2认证 wpa_cli -i wlan0 set_network 0 phase2 "auth=MSCHAPV2" # 设置身份和密码 wpa_cli -i wlan0 set_network 0 identity "\"你的用户名\"" wpa_cli -i wlan0 set_network 0 password "\"你的密码\"" # 启用该网络 wpa_cli -i wlan0 enable_network 0
注意:此方案需要设备已root,且APP能获取root执行权限。
最优建议
直接联系IM30设备厂商,获取官方开发文档或SDK,部分定制设备会提供合法修改系统配置的权限或接口,这是最稳定的解决方案。
内容的提问来源于stack exchange,提问作者Manuel Lucas

