You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flutter应用在iOS和Android设备上获取接入点列表

Flutter 获取iOS/Android可用WiFi接入点列表实现方案

核心思路

Flutter无原生API直接获取WiFi接入点,需借助第三方插件实现,推荐使用wifi_iot(跨平台支持完善)或flutter_wifi_scan(专注扫描功能)。以下以wifi_iot为例,分平台说明配置与代码实现。


Android 端配置与权限

  1. 添加权限到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标记,同时确保位置服务已开启。

  2. 位置服务要求
    Android系统强制要求:扫描WiFi必须开启设备位置服务,否则扫描结果为空。


iOS 端配置与权限

  1. 添加权限描述到Info.plist
    需添加位置权限相关描述,否则App会被拒:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>需要访问位置信息以扫描附近WiFi网络</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>需要持续访问位置信息以扫描附近WiFi网络</string>
    <key>NSLocationDefaultAccuracyReduced</key>
    <false/>
    

    注:iOS 14+必须开启精确位置,否则无法获取WiFi扫描结果。

  2. 系统限制
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:20:04