Flutter点对点通信插件flutter_p2p_plus的使用
Flutter点对点通信插件flutter_p2p_plus的使用
获取开始
必要权限
在AndroidManifest.xml文件中添加以下权限:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
请求权限
为了扫描设备和连接到设备,需要请求位置权限:
Future<bool> _checkPermission() async {
if (!await FlutterP2pPlus.isLocationPermissionGranted()) {
await FlutterP2pPlus.requestLocationPermission();
return false;
}
return true;
}
注册与注销WiFi事件
为了接收连接状态变化或设备变化(如发现的设备等)的通知,你需要订阅wifiEvents
并注册插件以接收原生事件。
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
_register();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_register();
} else if (state == AppLifecycleState.paused) {
_unregister();
}
}
List<StreamSubscription> _subscriptions = [];
void _register() async {
if (!await _checkPermission()) {
return;
}
_subscriptions.add(FlutterP2pPlus.wifiEvents.stateChange!.listen((change) {
// 处理WiFi状态变化
}));
_subscriptions.add(FlutterP2pPlus.wifiEvents.connectionChange!.listen((change) {
// 处理连接状态变化
}));
_subscriptions.add(FlutterP2pPlus.wifiEvents.thisDeviceChange!.listen((change) {
// 处理本机设备变化
}));
_subscriptions.add(FlutterP2pPlus.wifiEvents.peersChange!.listen((change) {
// 处理发现的设备
}));
_subscriptions.add(FlutterP2pPlus.wifiEvents.discoveryChange!.listen((change) {
// 处理发现状态变化
}));
FlutterP2pPlus.register(); // 注册到原生事件流
}
void _unregister() {
_subscriptions.forEach((subscription) => subscription.cancel()); // 取消订阅
FlutterP2pPlus.unregister(); // 取消注册
}
}
发现设备
注册后,只需调用FlutterP2pPlus.discoverDevices()
方法来发现设备。
List<WifiP2pDevice> _peers = [];
void _register() async {
/// ...
_subscriptions.add(FlutterP2pPlus.wifiEvents.peersChange!.listen((change) {
setState(() {
_peers = change.devices;
});
}));
/// ...
}
void _discover() {
FlutterP2pPlus.discoverDevices();
}
连接到设备
调用FlutterP2pPlus.connect(device)
并监听FlutterP2pPlus.wifiEvents.connectionChange
。
bool _isConnected = false;
bool _isHost = false;
String _deviceAddress = "";
void _register() async {
// ...
_subscriptions.add(FlutterP2pPlus.wifiEvents.connectionChange!.listen((change) {
setState(() {
_isConnected = change.networkInfo.isConnected;
_isHost = change.wifiP2pInfo.isGroupOwner;
_deviceAddress = change.wifiP2pInfo.groupOwnerAddress;
});
}));
// ...
}
断开当前P2P组
调用FlutterP2pPlus.removeGroup()
。
void _disconnect() async {
FlutterP2pPlus.removeGroup();
}
在设备之间传输数据
连接到设备后,可以在客户端和主机之间异步传输数据。
主机端
// 打开端口并接受连接
P2pSocket? _socket;
void _openPortAndAccept(int port) async {
var socket = await FlutterP2pPlus.openHostPort(port);
setState(() {
_socket = socket;
});
var buffer = "";
socket?.inputStream.listen((data) {
var msg = String.fromCharCodes(data.data);
buffer += msg;
if (data.dataAvailable == 0) {
snackBar("Data Received from ${_isHost ? "Client" : "Host"}: $buffer");
socket.writeString("Successfully received: $buffer");
buffer = "";
}
});
debugPrint("_openPort done");
_isOpen = await FlutterP2pPlus.acceptPort(port) ?? false;
debugPrint("_accept done: $_isOpen");
}
客户端端
// 连接到端口并创建一个套接字
P2pSocket? _socket;
_connectToPort(int port) async {
var socket = await FlutterP2pPlus.connectToHost(
_deviceAddress, // 见上方“连接到设备”
port,
timeout: 100000, // 超时时间(默认为500毫秒)
);
setState(() {
_socket = socket;
});
_socket?.inputStream.listen((data) {
var msg = utf8.decode(data.data);
snackBar("Received from ${_isHost ? "Host" : "Client"} $msg");
});
debugPrint("_connectToPort done");
}
更多关于Flutter点对点通信插件flutter_p2p_plus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter点对点通信插件flutter_p2p_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_p2p_plus
是一个用于在 Flutter 中实现点对点(P2P)通信的插件。它允许设备之间直接通信,而无需通过中央服务器。这对于需要在本地网络中直接交换数据的应用程序非常有用。
以下是使用 flutter_p2p_plus
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 flutter_p2p_plus
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_p2p_plus: ^0.0.1 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 初始化插件
在你的 Dart 代码中,首先需要初始化 flutter_p2p_plus
插件:
import 'package:flutter_p2p_plus/flutter_p2p_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterP2pPlus.initialize();
runApp(MyApp());
}
3. 发现设备
使用 flutter_p2p_plus
插件,你可以发现附近的设备。以下是一个简单的示例:
void discoverPeers() async {
try {
List<Peer> peers = await FlutterP2pPlus.discoverPeers();
for (var peer in peers) {
print('Discovered peer: ${peer.deviceName}');
}
} catch (e) {
print('Failed to discover peers: $e');
}
}
4. 连接到设备
发现设备后,你可以选择连接到某个设备:
void connectToPeer(Peer peer) async {
try {
await FlutterP2pPlus.connect(peer);
print('Connected to ${peer.deviceName}');
} catch (e) {
print('Failed to connect to peer: $e');
}
}
5. 发送和接收数据
连接成功后,你可以发送和接收数据。以下是一个简单的示例:
void sendMessage(String message) async {
try {
await FlutterP2pPlus.sendMessage(message);
print('Message sent: $message');
} catch (e) {
print('Failed to send message: $e');
}
}
void receiveMessage() async {
try {
String message = await FlutterP2pPlus.receiveMessage();
print('Message received: $message');
} catch (e) {
print('Failed to receive message: $e');
}
}
6. 断开连接
当你不再需要与设备通信时,可以断开连接:
void disconnect() async {
try {
await FlutterP2pPlus.disconnect();
print('Disconnected from peer');
} catch (e) {
print('Failed to disconnect: $e');
}
}
7. 处理权限
在使用 flutter_p2p_plus
插件时,确保你已经在 AndroidManifest.xml
和 Info.plist
中请求了必要的权限。
Android
在 AndroidManifest.xml
中添加以下权限:
<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_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
iOS
在 Info.plist
中添加以下权限:
<key>NSBonjourServices</key>
<array>
<string>_flutterp2p._tcp</string>
</array>
<key>NSLocalNetworkUsageDescription</key>
<string>We need access to the local network to discover and connect to other devices.</string>
8. 完整示例
以下是一个完整的示例,展示了如何使用 flutter_p2p_plus
插件进行点对点通信:
import 'package:flutter/material.dart';
import 'package:flutter_p2p_plus/flutter_p2p_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterP2pPlus.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: P2PExample(),
);
}
}
class P2PExample extends StatefulWidget {
[@override](/user/override)
_P2PExampleState createState() => _P2PExampleState();
}
class _P2PExampleState extends State<P2PExample> {
List<Peer> peers = [];
Peer? connectedPeer;
void discoverPeers() async {
try {
List<Peer> discoveredPeers = await FlutterP2pPlus.discoverPeers();
setState(() {
peers = discoveredPeers;
});
} catch (e) {
print('Failed to discover peers: $e');
}
}
void connectToPeer(Peer peer) async {
try {
await FlutterP2pPlus.connect(peer);
setState(() {
connectedPeer = peer;
});
print('Connected to ${peer.deviceName}');
} catch (e) {
print('Failed to connect to peer: $e');
}
}
void sendMessage(String message) async {
try {
await FlutterP2pPlus.sendMessage(message);
print('Message sent: $message');
} catch (e) {
print('Failed to send message: $e');
}
}
void receiveMessage() async {
try {
String message = await FlutterP2pPlus.receiveMessage();
print('Message received: $message');
} catch (e) {
print('Failed to receive message: $e');
}
}
void disconnect() async {
try {
await FlutterP2pPlus.disconnect();
setState(() {
connectedPeer = null;
});
print('Disconnected from peer');
} catch (e) {
print('Failed to disconnect: $e');
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter P2P Example'),
),
body: Column(
children: [
ElevatedButton(
onPressed: discoverPeers,
child: Text('Discover Peers'),
),
Expanded(
child: ListView.builder(
itemCount: peers.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(peers[index].deviceName),
onTap: () => connectToPeer(peers[index]),
);
},
),
),
if (connectedPeer != null) ...[
ElevatedButton(
onPressed: () => sendMessage('Hello, ${connectedPeer!.deviceName}!'),
child: Text('Send Message'),
),
ElevatedButton(
onPressed: receiveMessage,
child: Text('Receive Message'),
),
ElevatedButton(
onPressed: disconnect,
child: Text('Disconnect'),
),
],
],
),
);
}
}