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

如何在Flutter应用及Android Things设备中集成Google Nearby API实现WiFi相关操作?

嘿,我来分享下这两个场景的具体实现方案,都是我实际项目里踩过坑后总结的经验~

1. 在Flutter应用中集成Google Nearby API实现WiFi凭证共享

因为Flutter官方没有直接封装Nearby API,所以咱们得通过Platform Channel对接Android原生的Nearby Connections API(iOS端WiFi凭证共享限制较多,这里重点讲Android):

步骤1:配置Android项目依赖

打开android/app/build.gradle,添加Nearby Connections的依赖:

dependencies {
    // 其他依赖...
    implementation 'com.google.android.gms:play-services-nearby:18.0.0' // 选最新稳定版
}

步骤2:申请必要权限

在AndroidManifest.xml里声明权限,注意Android版本差异:

<!-- 基础权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

<!-- Android 12+ 新增蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

别忘了在Flutter端或者原生端动态申请权限,因为位置、蓝牙权限需要用户手动授权。

步骤3:原生Android端实现核心逻辑

创建一个NearbyWifiSharePlugin类,通过MethodChannel和Flutter通信:

关键代码片段:

public class NearbyWifiSharePlugin implements MethodCallHandler {
    private final Context context;
    private NearbyConnectionsClient nearbyClient;
    private WifiManager wifiManager;

    private NearbyWifiSharePlugin(Context context) {
        this.context = context;
        nearbyClient = Nearby.getConnectionsClient(context);
        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    }

    // 注册MethodChannel
    public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "nearby_wifi_share");
        channel.setMethodCallHandler(new NearbyWifiSharePlugin(registrar.context()));
    }

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        switch (call.method) {
            case "shareWifi":
                shareCurrentWifiCredentials();
                result.success("开始共享WiFi凭证");
                break;
            case "receiveWifi":
                startReceivingWifiCredentials();
                result.success("开始监听WiFi凭证");
                break;
            default:
                result.notImplemented();
        }
    }

    // 共享当前WiFi凭证
    private void shareCurrentWifiCredentials() {
        // 获取当前连接的WiFi信息(Android 10+需要位置权限开启才能拿到SSID)
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        String ssid = wifiInfo.getSSID().replace("\"", "");
        // 注意:普通APP无法直接读取系统保存的WiFi密码,这里建议用用户输入的凭证或应用自身存储的密码
        String password = "user_input_password"; 
        String encryptionType = "WPA2"; // 根据实际网络类型调整

        // 打包成JSON发送
        String credentials = "{\"ssid\":\"" + ssid + "\",\"password\":\"" + password + "\",\"type\":\"" + encryptionType + "\"}";

        // 初始化Nearby广播,等待接收方连接
        nearbyClient.startAdvertising(
                "WiFi共享发起方",
                "com.your.package.wifi_share",
                connectionLifecycleCallback,
                new AdvertisingOptions.Builder().setStrategy(Strategy.P2P_STAR).build()
        );
    }

    // 接收WiFi凭证并连接
    private void startReceivingWifiCredentials() {
        nearbyClient.startDiscovery(
                "com.your.package.wifi_share",
                endpointDiscoveryCallback,
                new DiscoveryOptions.Builder().setStrategy(Strategy.P2P_STAR).build()
        );
    }

    // 连接生命周期回调
    private final ConnectionLifecycleCallback connectionLifecycleCallback = new ConnectionLifecycleCallback() {
        @Override
        public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {
            // 接受连接请求
            nearbyClient.acceptConnection(endpointId, payloadCallback);
        }

        @Override
        public void onConnectionResult(String endpointId, ConnectionResolution result) {
            if (result.getStatus().isSuccess()) {
                // 连接成功,发送WiFi凭证
                nearbyClient.sendPayload(endpointId, Payload.fromBytes(credentials.getBytes()));
            }
        }

        @Override
        public void onDisconnected(String endpointId) {}
    };

    // 数据接收回调
    private final PayloadCallback payloadCallback = new PayloadCallback() {
        @Override
        public void onPayloadReceived(String endpointId, Payload payload) {
            if (payload.getType() == Payload.Type.BYTES) {
                String credentials = new String(payload.asBytes());
                // 解析JSON获取SSID和密码
                try {
                    JSONObject json = new JSONObject(credentials);
                    String ssid = json.getString("ssid");
                    String password = json.getString("password");
                    
                    // 配置并连接WiFi
                    WifiConfiguration config = new WifiConfiguration();
                    config.SSID = "\"" + ssid + "\"";
                    config.preSharedKey = "\"" + password + "\"";
                    int networkId = wifiManager.addNetwork(config);
                    wifiManager.enableNetwork(networkId, true);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onPayloadTransferUpdate(String endpointId, PayloadTransferUpdate update) {}
    };

    // 端点发现回调
    private final EndpointDiscoveryCallback endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
        @Override
        public void onEndpointFound(String endpointId, DiscoveredEndpointInfo info) {
            // 请求连接到发起方
            nearbyClient.requestConnection(
                    "WiFi接收方",
                    endpointId,
                    connectionLifecycleCallback
            );
        }

        @Override
        public void onEndpointLost(String endpointId) {}
    };
}

步骤4:Flutter端调用原生方法

创建MethodChannel,调用原生的共享和接收方法:

import 'package:flutter/services.dart';
import 'dart:convert';

class NearbyWifiShare {
  static const MethodChannel _channel = MethodChannel('nearby_wifi_share');

  static Future<String> shareWifi() async {
    final String result = await _channel.invokeMethod('shareWifi');
    return result;
  }

  static Future<String> receiveWifi() async {
    final String result = await _channel.invokeMethod('receiveWifi');
    return result;
  }
}

之后在UI里添加按钮调用这两个方法即可完成交互。


2. Android Things设备与Flutter应用通过Google Nearby API通信搭建本地WiFi

Android Things本质上是简化版的Android系统,所以同样可以集成Nearby Connections API,和Flutter应用(通过Platform Channel对接的Nearby)实现跨设备通信,进而搭建本地WiFi网络。

核心场景

分两种常见使用方式:

  1. Android Things创建WiFi热点:Flutter应用发送热点配置给设备,设备创建热点后,Flutter应用连接形成本地网络。
  2. Android Things连接现有WiFi:Flutter应用共享当前WiFi凭证给设备,设备连接到同一局域网。

步骤1:Android Things端配置

  • 创建Android Things项目,添加和之前一致的Nearby Connections依赖。
  • 在AndroidManifest.xml里声明相同的权限(Android Things可能默认开启部分权限,但仍需显式声明)。
  • 确保开发板(比如Raspberry Pi 3/4)支持蓝牙和WiFi硬件。

步骤2:Android Things端实现通信与WiFi控制

创建一个后台Service处理Nearby通信和WiFi操作:

public class NearbyIotService extends Service {
    private NearbyConnectionsClient nearbyClient;
    private WifiManager wifiManager;

    @Override
    public void onCreate() {
        super.onCreate();
        nearbyClient = Nearby.getConnectionsClient(this);
        wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
        startDiscovery(); // 启动发现Flutter应用的端点
    }

    private void startDiscovery() {
        nearbyClient.startDiscovery(
                "com.your.package.iot_comm",
                new EndpointDiscoveryCallback() {
                    @Override
                    public void onEndpointFound(String endpointId, DiscoveredEndpointInfo info) {
                        // 请求连接到Flutter应用
                        nearbyClient.requestConnection(
                                "Android Things设备",
                                endpointId,
                                connectionLifecycleCallback
                        );
                    }

                    @Override
                    public void onEndpointLost(String endpointId) {}
                },
                new DiscoveryOptions.Builder().setStrategy(Strategy.P2P_STAR).build()
        );
    }

    private final ConnectionLifecycleCallback connectionLifecycleCallback = new ConnectionLifecycleCallback() {
        @Override
        public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {
            nearbyClient.acceptConnection(endpointId, payloadCallback);
        }

        @Override
        public void onConnectionResult(String endpointId, ConnectionResolution result) {
            if (result.getStatus().isSuccess()) {
                // 连接成功,等待接收指令
            }
        }

        @Override
        public void onDisconnected(String endpointId) {}
    };

    private final PayloadCallback payloadCallback = new PayloadCallback() {
        @Override
        public void onPayloadReceived(String endpointId, Payload payload) {
            if (payload.getType() == Payload.Type.BYTES) {
                String command = new String(payload.asBytes());
                try {
                    JSONObject json = new JSONObject(command);
                    String action = json.getString("action");

                    switch (action) {
                        case "CREATE_HOTSPOT":
                            String ssid = json.getString("ssid");
                            String password = json.getString("password");
                            createWifiHotspot(ssid, password);
                            break;
                        case "CONNECT_WIFI":
                            String wifiSsid = json.getString("ssid");
                            String wifiPassword = json.getString("password");
                            connectToWifi(wifiSsid, wifiPassword);
                            break;
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onPayloadTransferUpdate(String endpointId, PayloadTransferUpdate update) {}
    };

    // 创建WiFi热点
    private void createWifiHotspot(String ssid, String password) {
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + ssid + "\"";
        config.preSharedKey = "\"" + password + "\"";
        config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

        wifiManager.setWifiEnabled(false);
        wifiManager.setWifiApEnabled(config, true);
    }

    // 连接到指定WiFi
    private void connectToWifi(String ssid, String password) {
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + ssid + "\"";
        config.preSharedKey = "\"" + password + "\"";
        int networkId = wifiManager.addNetwork(config);
        wifiManager.enableNetwork(networkId, true);
        wifiManager.setWifiEnabled(true);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

记得在AndroidManifest.xml里注册这个Service。

步骤3:Flutter端发送控制指令

通过MethodChannel调用原生发送方法,传递控制指令:

import 'package:flutter/services.dart';
import 'dart:convert';

class NearbyIotComm {
  static const MethodChannel _channel = MethodChannel('nearby_iot_comm');

  static Future<void> sendCreateHotspot(String ssid, String password) async {
    final String command = jsonEncode({
      "action": "CREATE_HOTSPOT",
      "ssid": ssid,
      "password": password
    });
    await _channel.invokeMethod('sendCommand', command);
  }

  static Future<void> sendConnectWifi(String ssid, String password) async {
    final String command = jsonEncode({
      "action": "CONNECT_WIFI",
      "ssid": ssid,
      "password": password
    });
    await _channel.invokeMethod('sendCommand', command);
  }
}

原生端只需实现sendCommand方法,通过Nearby的sendPayload把指令发送给Android Things设备即可。

注意事项

  • 选择合适的Nearby策略:Strategy.P2P_STAR适合一对多控制(一个Flutter应用管理多个IoT设备),Strategy.P2P_CLUSTER适合多设备间互相通信。
  • 添加重连逻辑:处理连接断开的情况,确保通信稳定性。
  • 硬件兼容性:部分开发板可能需要手动开启蓝牙/WiFi硬件开关,提前测试确认。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:42:00