Flutter应用内WiFi列表展示与连接功能实现求助
Flutter WiFi扫描与连接问题解决方案
一、先确认权限配置(核心前提)
很多连接失败的根源是权限没配全或未动态申请,针对Android和iOS分别检查:
Android端(AndroidManifest.xml)
<!-- 基础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.ACCESS_FINE_LOCATION" /> <!-- Android 12+ 新增WiFi扫描权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> <!-- Android 10+ 后台操作需额外权限 --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
注意:仅配置Manifest不够,必须动态申请权限:
import 'package:permission_handler/permission_handler.dart'; Future<void> requestRequiredPermissions() async { final locationStatus = await Permission.location.request(); if (locationStatus.isGranted) { await Permission.nearbyWifiDevices.request(); // Android 12+ 专用 } }
iOS端(Info.plist)
添加以下键值对:
<key>NSLocationWhenInUseUsageDescription</key> <string>需要位置权限扫描WiFi网络</string> <key>NSLocalNetworkUsageDescription</key> <string>需要访问本地网络完成WiFi连接</string>
二、插件选择与正确用法
扫描WiFi:wifi_scan(稳定可靠)
确保扫描逻辑正确,获取完整的WiFi信息:
import 'package:wifi_scan/wifi_scan.dart'; Future<List<WiFiNetwork>> getWiFiList() async { final scanPermission = await WiFiScan.instance.canStartScan(); if (scanPermission != CanStartScan.yes) return []; await WiFiScan.instance.startScan(); await Future.delayed(const Duration(seconds: 2)); // 等待扫描完成 return await WiFiScan.instance.getScannedResults(); }
连接WiFi:重点匹配加密类型
如果之前用的插件连接失败,优先检查加密类型是否与WiFi匹配,这是最常见的坑:
import 'package:flutter_wifi_connect/flutter_wifi_connect.dart'; Future<bool> connectWiFi(String ssid, String password, String encryption) async { // encryption可选值:WPA, WPA2, WEP, NONE try { return await FlutterWifiConnect.connectToWifi( ssid: ssid, password: password, encryption: encryption, ); } catch (e) { print('连接异常:$e'); return false; } }
注意:隐藏SSID的WiFi需开启插件的
isHidden参数;Android 10+ 禁止后台自动连接,必须在前台操作。
替代方案:原生API调用(插件失效时)
如果第三方插件始终无法连接,可通过MethodChannel直接调用Android原生WifiManager:
// Dart端 static const MethodChannel _wifiChannel = MethodChannel('wifi_connect_channel'); Future<bool> connectNativeWiFi(String ssid, String password) async { try { return await _wifiChannel.invokeMethod('connect', { 'ssid': ssid, 'password': password, }); } catch (e) { return false; } }
// Android端(MainActivity.kt) class MainActivity : FlutterActivity() { private val CHANNEL = "wifi_connect_channel" private lateinit var wifiManager: WifiManager override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "connect") { val ssid = call.argument<String>("ssid") ?: "" val password = call.argument<String>("password") ?: "" val success = connectToTargetWiFi(ssid, password) result.success(success) } else { result.notImplemented() } } } private fun connectToTargetWiFi(ssid: String, password: String): Boolean { val config = WifiConfiguration().apply { this.SSID = "\"$ssid\"" this.preSharedKey = "\"$password\"" status = WifiConfiguration.Status.ENABLED allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK) allowedGroupCiphers.apply { set(WifiConfiguration.GroupCipher.TKIP) set(WifiConfiguration.GroupCipher.CCMP) } } val netId = wifiManager.addNetwork(config) if (netId == -1) return false wifiManager.disconnect() return wifiManager.enableNetwork(netId, true) && wifiManager.reconnect() } }
三、常见排查点
- 确认WiFi的SSID和密码完全正确(注意大小写、特殊字符)
- 检查加密类型匹配:WPA2-PSK的WiFi不能用WEP参数
- Android 10+ 设备必须在前台发起连接,后台操作会被系统拦截
- 部分定制系统(如MIUI、ColorOS)需手动给应用开启WiFi控制权限
- 测试时确保设备与WiFi热点距离足够近,信号强度正常
内容的提问来源于stack exchange,提问作者hilalsnli
相关产品推荐
相关产品推荐

