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

如何在Flutter中实现WiFi网络设备Mac地址列表查询?

实现Flutter中获取当前WiFi网络设备及Mac地址的方案

由于系统权限限制,多数Flutter第三方库无法直接获取局域网设备的Mac地址,下面提供原生平台集成的可行方案,通过Flutter与原生代码通信实现需求。

Android 端实现步骤

1. 配置权限

在android/app/src/main/AndroidManifest.xml中添加必要权限:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Android 12+ 额外需要 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

注:Android 10+ 无法直接获取设备自身Mac,但通过读取ARP缓存可获取局域网内其他设备的Mac地址。

2. 编写原生扫描代码

创建Java工具类读取ARP缓存:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class WifiDeviceScanner {
    public static List<String> getConnectedDevices() {
        List<String> devices = new ArrayList<>();
        try {
            Process process = Runtime.getRuntime().exec("arp -a");
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split("\\s+");
                if (parts.length >= 2) {
                    String ip = parts[0];
                    String mac = parts[1];
                    devices.add("IP: " + ip + " | Mac: " + mac);
                }
            }
            reader.close();
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return devices;
    }
}

在MainActivity中注册MethodChannel与Flutter通信:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.example.wifi_scanner/device"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getConnectedDevices") {
                val devices = WifiDeviceScanner.getConnectedDevices()
                result.success(devices)
            } else {
                result.notImplemented()
            }
        }
    }
}

3. Flutter端调用

import 'package:flutter/services.dart';

class WifiDeviceService {
  static const MethodChannel _channel = MethodChannel('com.example.wifi_scanner/device');

  static Future<List<String>?> getConnectedDevices() async {
    try {
      final List<dynamic> result = await _channel.invokeMethod('getConnectedDevices');
      return result.cast<String>();
    } on PlatformException catch (e) {
      print("扫描失败: ${e.message}");
      return null;
    }
  }
}

在UI中调用该方法,将返回的设备列表渲染即可。

iOS 端实现步骤

iOS隐私限制更严格,仅能通过arp命令尝试获取ARP缓存,且需用户授权局域网访问。

1. 配置权限

在ios/Runner/Info.plist中添加:

<key>NSLocalNetworkUsageDescription</key>
<string>需要访问局域网以扫描连接设备</string>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

2. 编写原生扫描代码

创建Swift工具类:

import Foundation

class WifiDeviceScanner {
    static func getConnectedDevices() -> [String] {
        var devices = [String]()
        let task = Process()
        task.executableURL = URL(fileURLWithPath: "/usr/sbin/arp")
        task.arguments = ["-a"]
        
        let pipe = Pipe()
        task.standardOutput = pipe
        
        do {
            try task.run()
            let data = pipe.fileHandleForReading.readDataToEndOfFile()
            guard let output = String(data: data, encoding: .utf8) else { return devices }
            
            let lines = output.components(separatedBy: "\n")
            for line in lines {
                let parts = line.components(separatedBy: .whitespaces).filter { !$0.isEmpty }
                if parts.count >= 2 {
                    let ip = parts[0]
                    let mac = parts[1]
                    devices.append("IP: \(ip) | Mac: \(mac)")
                }
            }
            task.waitUntilExit()
        } catch {
            print(error.localizedDescription)
        }
        return devices
    }
}

在AppDelegate中注册MethodChannel:

import Flutter
import UIKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private let CHANNEL = "com.example.wifi_scanner/device"
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller = window?.rootViewController as! FlutterViewController
        let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger)
        channel.setMethodCallHandler { call, result in
            if call.method == "getConnectedDevices" {
                let devices = WifiDeviceScanner.getConnectedDevices()
                result.success(devices)
            } else {
                result.notImplemented()
            }
        }
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

Flutter端调用逻辑与Android完全一致。

注意事项

  • Android 10+ 必须申请位置权限,否则无法读取ARP缓存;
  • iOS 14+ 部分设备Mac地址可能显示为incomplete,受系统隐私限制;
  • 部分路由器会隐藏设备Mac地址,导致无法获取。

内容的提问来源于stack exchange,提问作者Aldama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:10:24