如何使用Flutter应用在iOS和Android设备上获取接入点列表
Flutter 获取iOS/Android可用WiFi接入点列表实现方案
核心思路
Flutter无原生API直接获取WiFi接入点,需借助第三方插件实现,推荐使用wifi_iot(跨平台支持完善)或flutter_wifi_scan(专注扫描功能)。以下以wifi_iot为例,分平台说明配置与代码实现。
Android 端配置与权限
添加权限到
AndroidManifest.xml
根据Android版本差异配置权限:<!-- 基础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_NETWORK_STATE" /> <!-- Android 10及以上:扫描WiFi需位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12+:新增NEARBY_WIFI_DEVICES权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />注:若需获取WiFi的BSSID、信号强度等关联位置的信息,需移除
neverForLocation标记,同时确保位置服务已开启。位置服务要求
Android系统强制要求:扫描WiFi必须开启设备位置服务,否则扫描结果为空。
iOS 端配置与权限
添加权限描述到
Info.plist
需添加位置权限相关描述,否则App会被拒:<key>NSLocationWhenInUseUsageDescription</key> <string>需要访问位置信息以扫描附近WiFi网络</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>需要持续访问位置信息以扫描附近WiFi网络</string> <key>NSLocationDefaultAccuracyReduced</key> <false/>注:iOS 14+必须开启精确位置,否则无法获取WiFi扫描结果。
系统限制
iOS对WiFi扫描频率有严格限制,短时间内多次调用会被系统拦截,建议控制扫描间隔在10秒以上。
代码实现步骤
1. 添加依赖
在pubspec.yaml中添加插件依赖:
dependencies: flutter: sdk: flutter wifi_iot: ^0.3.15 permission_handler: ^10.2.0 # 用于权限请求 device_info_plus: ^9.0.2 # 用于判断Android版本
2. 权限请求与扫描逻辑
import 'package:flutter/material.dart'; import 'package:wifi_iot/wifi_iot.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; class WifiScanner extends StatefulWidget { const WifiScanner({super.key}); @override State<WifiScanner> createState() => _WifiScannerState(); } class _WifiScannerState extends State<WifiScanner> { List<WifiNetwork> _wifiList = []; bool _isScanning = false; // 请求必要权限 Future<bool> _requestPermissions() async { final deviceInfo = DeviceInfoPlugin(); if (Theme.of(context).platform == TargetPlatform.android) { final androidInfo = await deviceInfo.androidInfo; if (androidInfo.version.sdkInt >= 31) { // Android 12+ 先请求NEARBY_WIFI_DEVICES final wifiStatus = await Permission.nearbyWifiDevices.request(); if (!wifiStatus.isGranted) return false; } // 所有Android版本都需要位置权限 final locationStatus = await Permission.locationWhenInUse.request(); return locationStatus.isGranted; } else if (Theme.of(context).platform == TargetPlatform.iOS) { // iOS 请求位置权限+精确位置 final locationStatus = await Permission.locationWhenInUse.request(); final accuracyStatus = await Permission.locationAccuracy.request(); return locationStatus.isGranted && accuracyStatus.isGranted; } return false; } // 执行WiFi扫描 Future<void> _scanWifi() async { setState(() => _isScanning = true); try { final hasPermission = await _requestPermissions(); if (!hasPermission) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("权限不足,无法扫描WiFi")), ); return; } // 确保WiFi已开启 final isWifiEnabled = await WiFiForIoTPlugin.isWiFiEnabled(); if (!isWifiEnabled) { await WiFiForIoTPlugin.setWiFiEnabled(true); await Future.delayed(const Duration(seconds: 2)); // 等待WiFi启动 } // 获取扫描结果 final wifiList = await WiFiForIoTPlugin.loadWifiList(); setState(() => _wifiList = wifiList); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("扫描失败:${e.toString()}")), ); } finally { setState(() => _isScanning = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("WiFi接入点扫描")), body: Column( children: [ ElevatedButton( onPressed: _isScanning ? null : _scanWifi, child: _isScanning ? const CircularProgressIndicator(color: Colors.white) : const Text("开始扫描"), ), Expanded( child: ListView.builder( itemCount: _wifiList.length, itemBuilder: (context, index) { final wifi = _wifiList[index]; return ListTile( title: Text(wifi.ssid ?? "无名称"), subtitle: Text("信号强度:${wifi.rssi}dBm | BSSID:${wifi.bssid}"), ); }, ), ), ], ), ); } }
关键注意事项
- 真机测试:模拟器不支持WiFi扫描功能,必须使用物理设备测试。
- 位置服务强制要求:Android和iOS都需要开启位置服务才能获取扫描结果,需在App中提示用户开启。
- 扫描频率限制:iOS系统对扫描频次有严格限制,避免短时间内重复调用扫描接口。
- 插件兼容性:部分插件在最新系统版本(如Android 14、iOS 17)可能存在适配问题,建议选择维护活跃的插件版本。
内容的提问来源于stack exchange,提问作者riki
相关产品推荐
相关产品推荐

