Flutter中如何在其他设备扫描本设备二维码后触发本设备状态变更
Flutter双端扫码联动状态更新实现方案
核心需求是两个独立应用的跨端通信:扫描端识别二维码成功后,给生成端发送触发信号,生成端收到信号后更新本地状态。根据你的使用场景可以选择以下3种落地方案:
方案1:局域网WebSocket通信(同WiFi场景首选,无额外成本)
适用场景:两个设备连接同一个WiFi,不需要跨网络使用。
实现步骤:
- 生成端启动本地WebSocket服务,将自身的局域网IP+服务端口拼入二维码内容
- 扫描端扫码成功后,解析二维码中的WebSocket服务地址,建立连接后发送
scan_success标识信号 - 生成端监听到信号后直接触发状态更新
所需依赖(添加到pubspec.yaml):
dependencies: shelf: ^1.4.0 shelf_web_socket: ^1.0.4 web_socket_channel: ^2.4.0
生成端启动服务代码示例:
import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:shelf_web_socket/shelf_web_socket.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; WebSocketChannel? connectedClient; Future<void> startLocalSocketServer() async { final handler = webSocketHandler((channel) { connectedClient = channel; // 监听扫描端发送的消息 channel.stream.listen((message) { if (message == "scan_success") { // 此处更新你需要的UI状态即可 print("已收到扫描成功信号,更新状态"); } }); }); // 绑定本地8888端口,0.0.0.0允许同局域网设备访问 final server = await shelf_io.serve(handler, '0.0.0.0', 8888); final serviceAddr = "ws://${server.address.address}:${server.port}"; print("Socket服务已启动,地址:$serviceAddr,将该地址拼入二维码内容即可"); }
扫描端扫码成功后发信代码示例:
import 'package:web_socket_channel/web_socket_channel.dart'; void handleScanResult(String qrContent) async { // 这里qrContent就是二维码里的WebSocket服务地址 final channel = WebSocketChannel.connect(Uri.parse(qrContent)); channel.sink.add("scan_success"); // 发送完成后关闭连接释放资源 await Future.delayed(const Duration(milliseconds: 500)); await channel.sink.close(); }
注意:需要为两个应用申请局域网访问、本地网络权限,iOS还需要在Info.plist中配置NSLocalNetworkUsageDescription权限说明。
方案2:公网实时数据库中转(跨网络场景首选)
适用场景:两个设备不在同一个局域网,需要跨网络联动。
实现步骤:
- 生成端生成全局唯一的业务ID,将该ID拼入二维码内容,同时监听云数据库中该ID对应记录的状态
- 扫描端扫码成功后,修改云数据库中对应ID的状态为
已扫描 - 生成端监听到数据库状态变更后,触发本地状态更新即可
- 可以选用任意支持实时监听的云数据库实现,不需要自行搭建后端服务。
方案3:同设备双应用联动方案
适用场景:生成端和扫描端两个应用安装在同一台设备上。
实现步骤:
- 给生成端应用配置自定义URL Scheme,比如
qrcode_generator:// - 扫描端扫码成功后,调用系统接口跳转
qrcode_generator://scan_success - 生成端监听入站的跳转请求,识别到
scan_success参数后直接更新状态即可
内容的提问来源于stack exchange,提问作者Antonio Ceasar
相关产品推荐
相关产品推荐

