WiFi Direct Plugin

A comprehensive Flutter plugin for peer-to-peer device communication using WiFi Direct on Android and MultipeerConnectivity on iOS. Enable seamless device-to-device communication without requiring an internet connection.

Features

🔗 Cross-Platform P2P Communication

  • Android: WiFi P2P (WiFi Direct) support
  • iOS: MultipeerConnectivity framework integration

📱 Device Discovery & Connection

  • Automatic peer discovery
  • Server/Client connection models
  • Real-time connection status monitoring

💬 Multi-Type Data Transfer

  • Text messaging
  • File transfer with progress tracking
  • Image sharing with chunked transmission
  • Binary data communication

🔄 Reliable Communication

  • Automatic message buffering and reassembly
  • MD5 checksum verification for file integrity
  • Connection resilience with automatic reconnection

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  wifi_direct_plugin: ^0.1.7

Then run:

flutter pub get

Platform Setup

Android Setup

Add the following permissions to your android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<uses-feature android:name="android.hardware.wifi.direct" android:required="true" />

iOS Setup

Add the following to your ios/Runner/Info.plist:

<key>NSLocalNetworkUsageDescription</key>
<string>This app needs to access your local network for WiFi Direct communication</string>
<key>NSBonjourServices</key>
<array>
    <string>_wifi-direct._tcp</string>
    <string>_wifi-direct._udp</string>
</array>

Quick Start

1. Initialize the Plugin

import 'package:wifi_direct_plugin/wifi_direct_plugin.dart';

// Initialize the plugin
await WifiDirectPlugin.initialize();

2. Setup Event Listeners

// Listen for connection changes
WifiDirectPlugin.connectionStream.listen((connectionInfo) {
  print('Connection status: ${connectionInfo.isConnected}');
  print('Is Group Owner: ${connectionInfo.isGroupOwner}');
});

// Listen for peer discovery
WifiDirectPlugin.peersStream.listen((peers) {
  print('Found ${peers.length} peers');
  for (var peer in peers) {
    print('Peer: ${peer.deviceName} (${peer.deviceAddress})');
  }
});

// Setup data reception callbacks
WifiDirectPlugin.onTextReceived = (text) {
  print('Received text: $text');
};

WifiDirectPlugin.onFileReceived = (file) {
  print('Received file: ${file.path}');
};

WifiDirectPlugin.onImageReceived = (image) {
  print('Received image: ${image.path}');
};

3. Start as Server or Client

// Start as server (Group Owner)
await WifiDirectPlugin.startAsServer('MyDevice');
await WifiDirectPlugin.startDiscovery();

// OR start as client
await WifiDirectPlugin.startAsClient('MyClientDevice');
await WifiDirectPlugin.startDiscovery();

4. Connect to Peers

// Connect to a discovered peer
await WifiDirectPlugin.connect(peerDeviceAddress);

5. Send Data

// Send text message
await WifiDirectPlugin.sendText('Hello, peer device!');

// Send file
await WifiDirectPlugin.sendFile('/path/to/your/file.pdf');

// Send image
await WifiDirectPlugin.sendImage('/path/to/your/image.jpg');

Advanced Usage

Progress Tracking

Monitor file and image transfer progress:

WifiDirectPlugin.onSendProgress = (fileName, progress) {
  print('Sending $fileName: ${(progress * 100).toStringAsFixed(1)}%');
};

WifiDirectPlugin.onFileProgress = (fileName, progress) {
  print('Receiving $fileName: ${(progress * 100).toStringAsFixed(1)}%');
};

Connection Management

// Get current connection info
WifiDirectConnectionInfo? info = await WifiDirectPlugin.getCurrentConnectionInfo();

// Get connected device details
Map<String, dynamic>? deviceInfo = await WifiDirectPlugin.getConnectedDeviceInfo();

// Get peer display information
String peerInfo = await WifiDirectPlugin.getPeerDisplayInfo();

// Disconnect from current peer
await WifiDirectPlugin.disconnect();

Complete Example

import 'package:flutter/material.dart';
import 'package:wifi_direct_plugin/wifi_direct_plugin.dart';

class WiFiDirectExample extends StatefulWidget {
  @override
  _WiFiDirectExampleState createState() => _WiFiDirectExampleState();
}

class _WiFiDirectExampleState extends State<WiFiDirectExample> {
  List<WifiDirectDevice> peers = [];
  bool isConnected = false;
  String connectionStatus = 'Disconnected';

  @override
  void initState() {
    super.initState();
    initializeWiFiDirect();
  }

  Future<void> initializeWiFiDirect() async {
    // Initialize plugin
    await WifiDirectPlugin.initialize();

    // Setup listeners
    WifiDirectPlugin.connectionStream.listen((info) {
      setState(() {
        isConnected = info.isConnected;
        connectionStatus = info.isConnected ? 'Connected' : 'Disconnected';
      });
    });

    WifiDirectPlugin.peersStream.listen((discoveredPeers) {
      setState(() {
        peers = discoveredPeers;
      });
    });

    WifiDirectPlugin.onTextReceived = (text) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Received: $text')),
      );
    };
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('WiFi Direct Example'),
      ),
      body: Column(
        children: [
          Text('Status: $connectionStatus'),
          ElevatedButton(
            onPressed: () async {
              await WifiDirectPlugin.startAsServer('MyDevice');
              await WifiDirectPlugin.startDiscovery();
            },
            child: Text('Start as Server'),
          ),
          ElevatedButton(
            onPressed: () async {
              await WifiDirectPlugin.startAsClient('MyClient');
              await WifiDirectPlugin.startDiscovery();
            },
            child: Text('Start as Client'),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: peers.length,
              itemBuilder: (context, index) {
                final peer = peers[index];
                return ListTile(
                  title: Text(peer.deviceName),
                  subtitle: Text(peer.deviceAddress),
                  onTap: () async {
                    await WifiDirectPlugin.connect(peer.deviceAddress);
                  },
                );
              },
            ),
          ),
          if (isConnected)
            ElevatedButton(
              onPressed: () async {
                await WifiDirectPlugin.sendText('Hello from Flutter!');
              },
              child: Text('Send Message'),
            ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    WifiDirectPlugin.cleanup();
    super.dispose();
  }
}

API Reference

Core Methods

Method Description
initialize() Initialize the WiFi Direct plugin
startAsServer(deviceName) Start as server/group owner
startAsClient(deviceName) Start as client
startDiscovery() Begin peer discovery
stopDiscovery() Stop peer discovery
connect(deviceAddress) Connect to a specific peer
disconnect() Disconnect from current peer
cleanup() Clean up plugin resources

Data Transfer Methods

Method Description
sendText(text) Send text message
sendFile(filePath) Send file with progress tracking
sendImage(imagePath) Send image with chunked transfer

Information Methods

Method Return Type Description
getCurrentConnectionInfo() WifiDirectConnectionInfo? Get current connection details
getConnectedDeviceInfo() Map<String, dynamic>? Get connected device information
getPeerDisplayInfo() String Get formatted peer information
getPeerIpAddress() String? Get peer IP address

Streams and Callbacks

Stream/Callback Type Description
connectionStream Stream<WifiDirectConnectionInfo> Connection status updates
peersStream Stream<List<WifiDirectDevice>> Discovered peers
onTextReceived Function(String) Text message received
onFileReceived Function(File) File received
onImageReceived Function(File) Image received
onSendProgress Function(String, double) Send progress updates
onFileProgress Function(String, double) Receive progress updates

Requirements

Android

  • Minimum SDK: API 21 (Android 5.0)
  • WiFi Direct capable device
  • Location permissions for peer discovery

iOS

  • Minimum version: iOS 9.0
  • MultipeerConnectivity framework support
  • Local network access permissions

Limitations

  • Range: Communication range depends on WiFi Direct/MultipeerConnectivity capabilities (typically 30-200 meters)
  • Device Limit: Limited number of simultaneous connections (typically 8 devices max)
  • iOS: Uses MultipeerConnectivity which may have different behavior compared to Android WiFi Direct
  • Background: Limited background operation support depending on platform

Contributing

Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for a detailed list of changes and updates.