wifi_direct_plugin 0.0.1 copy "wifi_direct_plugin: ^0.0.1" to clipboard
wifi_direct_plugin: ^0.0.1 copied to clipboard

A comprehensive Flutter plugin for WiFi Direct (P2P) communication with real-time messaging, file transfer, and cross-platform support for Android and iOS.

WiFi Direct Plugin #

pub package Platform License: MIT

A comprehensive Flutter plugin for WiFi Direct (P2P) communication, enabling direct device-to-device connections without requiring internet access. Perfect for building offline chat applications, file sharing tools, and collaborative apps.

🚀 Features #

Core Functionality #

  • 📱 Cross-Platform Support: Android (WiFi Direct) & iOS (MultipeerConnectivity)
  • 🔗 P2P Connection: Direct device-to-device communication without internet
  • 💬 Real-time Messaging: Instant text message exchange
  • 📁 File Transfer: Send any file type with progress tracking
  • 📸 Image Sharing: Camera capture and gallery selection
  • 🔄 Auto-Discovery: Automatic peer detection and connection

Advanced Features #

  • 📊 Progress Tracking: Real-time upload/download progress for both sender and receiver
  • 🔒 Data Integrity: MD5 checksum verification for file transfers
  • 💾 Smart Storage: Automatic saving to Downloads folder with duplicate handling
  • 🔄 Auto-Reconnection: Intelligent connection recovery mechanisms
  • 🎯 Connection Management: Host/Client roles with seamless switching
  • ⚠️ Error Handling: Comprehensive error detection and recovery

📱 Platform Support #

Platform Implementation Minimum Version
Android WiFi Direct (P2P) API API 16+ (Android 4.1+)
iOS MultipeerConnectivity iOS 9.0+
Flutter EventChannel & MethodChannel 3.0.0+

🏗️ Installation #

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

dependencies:
  wifi_direct_plugin: ^0.0.1

Then run:

flutter pub get

⚙️ Setup #

Android Configuration #

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" android:usesPermissionFlags="neverForLocation" />
    <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-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.wifi.direct" android:required="true" />

iOS Configuration #

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 WiFi Direct
bool success = await WifiDirectPlugin.initialize();
if (success) {
  print('WiFi Direct initialized successfully!');
}

2. Start as Host (Server) #

// Start as host to create a group
bool started = await WifiDirectPlugin.startAsServer(
  deviceName: "My Awesome Device"
);

if (started) {
  print('Host started! Waiting for connections...');
}

3. Join as Client #

// Start as client and discover devices
await WifiDirectPlugin.startAsClient(deviceName: "Client Device");
await WifiDirectPlugin.startDiscovery();

// Listen for discovered peers
WifiDirectPlugin.peersStream.listen((peers) {
  for (var peer in peers) {
    print('Found device: ${peer.deviceName}');
  }
});

// Connect to a device
await WifiDirectPlugin.connect(deviceAddress);

4. Send Messages and Files #

// Send text message
await WifiDirectPlugin.sendText("Hello, World!");

// Send file
await WifiDirectPlugin.sendFile("/path/to/document.pdf");

// Send image
await WifiDirectPlugin.sendImage("/path/to/photo.jpg");

5. Handle Incoming Data #

// Set up callbacks for received data
WifiDirectPlugin.onTextReceived = (text) {
  print('Received message: $text');
};

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

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

// Track transfer progress
WifiDirectPlugin.onFileProgress = (fileName, progress) {
  print('Receiving $fileName: ${(progress * 100).toInt()}%');
};

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

🎯 Complete Example #

Here's a complete example of a simple chat application:

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

class ChatScreen extends StatefulWidget {
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final TextEditingController _messageController = TextEditingController();
  final List<String> _messages = [];
  bool _isConnected = false;

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

  Future<void> _initializeWifiDirect() async {
    await WifiDirectPlugin.initialize();

    // Set up message receiver
    WifiDirectPlugin.onTextReceived = (text) {
      setState(() {
        _messages.add('Received: $text');
      });
    };

    // Listen for connection changes
    WifiDirectPlugin.connectionStream.listen((info) {
      setState(() {
        _isConnected = info.isConnected;
      });
    });
  }

  Future<void> _sendMessage() async {
    final message = _messageController.text.trim();
    if (message.isNotEmpty && _isConnected) {
      await WifiDirectPlugin.sendText(message);
      setState(() {
        _messages.add('Sent: $message');
        _messageController.clear();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_isConnected ? 'Connected' : 'Disconnected'),
        backgroundColor: _isConnected ? Colors.green : Colors.red,
      ),
      body: Column(
        children: [
          // Connection buttons
          if (!_isConnected) ...[
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: () => WifiDirectPlugin.startAsServer(),
                    child: Text('Host'),
                  ),
                ),
                SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    onPressed: () async {
                      await WifiDirectPlugin.startAsClient();
                      await WifiDirectPlugin.startDiscovery();
                    },
                    child: Text('Join'),
                  ),
                ),
              ],
            ),
          ],

          // Messages list
          Expanded(
            child: ListView.builder(
              itemCount: _messages.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(_messages[index]),
                );
              },
            ),
          ),

          // Message input
          if (_isConnected)
            Padding(
              padding: EdgeInsets.all(8.0),
              child: Row(
                children: [
                  Expanded(
                    child: TextField(
                      controller: _messageController,
                      decoration: InputDecoration(
                        hintText: 'Type a message...',
                        border: OutlineInputBorder(),
                      ),
                      onSubmitted: (_) => _sendMessage(),
                    ),
                  ),
                  SizedBox(width: 8),
                  IconButton(
                    onPressed: _sendMessage,
                    icon: Icon(Icons.send),
                  ),
                ],
              ),
            ),
        ],
      ),
    );
  }

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

📚 API Reference #

Core Methods #

Method Description Returns
initialize() Initialize WiFi Direct Future<bool>
startAsServer({String? deviceName}) Start as host/server Future<bool>
startAsClient({String? deviceName}) Start as client Future<bool>
startDiscovery() Begin peer discovery Future<bool>
stopDiscovery() Stop peer discovery Future<bool>
connect(String deviceAddress) Connect to peer Future<bool>
disconnect() Disconnect from peer Future<bool>

Messaging & Transfer #

Method Description Returns
sendText(String text) Send text message Future<bool>
sendFile(String filePath) Send file Future<bool>
sendImage(String imagePath) Send image Future<bool>

Event Streams #

Stream Description Data Type
peersStream Discovered peers Stream<List<WifiDirectDevice>>
connectionStream Connection status Stream<WifiDirectConnectionInfo>

Callbacks #

Callback Description Parameters
onTextReceived Text message received String text
onFileReceived File received File file
onImageReceived Image received File image
onFileProgress Receive progress String fileName, double progress
onSendProgress Send progress String fileName, double progress

🔧 Advanced Configuration #

Connection Management #

// Monitor connection state
WifiDirectPlugin.connectionStream.listen((info) {
  print('Connected: ${info.isConnected}');
  print('Is Group Owner: ${info.isGroupOwner}');
  print('Group Owner Address: ${info.groupOwnerAddress}');
});

// Handle peer discovery
WifiDirectPlugin.peersStream.listen((peers) {
  for (var peer in peers) {
    print('Device: ${peer.deviceName} (${peer.deviceAddress})');
  }
});

File Transfer with Progress #

// Track upload progress
WifiDirectPlugin.onSendProgress = (fileName, progress) {
  print('Uploading $fileName: ${(progress * 100).toInt()}%');
};

// Track download progress
WifiDirectPlugin.onFileProgress = (fileName, progress) {
  print('Downloading $fileName: ${(progress * 100).toInt()}%');
};

// Handle completed transfers
WifiDirectPlugin.onFileReceived = (file) async {
  // Save to Downloads folder
  String? savedPath = await FileService.saveFileToDownloads(
    file,
    file.path.split('/').last
  );
  print('File saved to: $savedPath');
};

🎨 UI Components #

The plugin includes pre-built UI components for quick integration:

  • ConnectionInfo: Shows current connection status
  • PeerList: Displays discovered devices
  • FileProgress: Shows transfer progress
  • MessageBubble: Chat message display
  • InputArea: Message input with file/image buttons

⚠️ Important Notes #

Android Considerations #

  • Permissions: Location permission is required for WiFi Direct discovery
  • WiFi State: Device WiFi must be enabled
  • Background: File transfers may be interrupted if app goes to background
  • Device Compatibility: Some manufacturers may have WiFi Direct limitations

iOS Considerations #

  • Proximity: Devices must be in close proximity for MultipeerConnectivity
  • Privacy: Users will see connection prompts
  • Background: Limited background execution capabilities

Performance Tips #

  • File Size: Large files are automatically chunked for efficient transfer
  • Network Quality: Transfer speed depends on WiFi Direct connection quality
  • Memory: Plugin efficiently manages memory for large file transfers
  • Battery: Continuous discovery can drain battery

🐛 Troubleshooting #

Common Issues #

Connection fails on Android:

  • Ensure location permission is granted
  • Check if WiFi is enabled
  • Try restarting WiFi Direct discovery

iOS devices not discovering each other:

  • Ensure devices are close to each other
  • Check Bluetooth and WiFi are enabled
  • Restart the app if needed

File transfer is slow:

  • WiFi Direct speed varies by device and distance
  • Close other network-intensive apps
  • Ensure devices are close to each other

Permission errors:

  • Check all required permissions are added to AndroidManifest.xml
  • Request runtime permissions properly
  • Test on different Android versions

🤝 Contributing #

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

📄 License #

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

🙏 Acknowledgments #

  • Flutter team for the excellent plugin architecture
  • Android WiFi Direct API documentation
  • iOS MultipeerConnectivity framework
  • Open source community for inspiration and feedback

📞 Support #

  • Examples: Check the /example folder for complete sample apps

Made with ❤️ for the Flutter community

1
likes
0
points
48
downloads

Publisher

unverified uploader

Weekly Downloads

A comprehensive Flutter plugin for WiFi Direct (P2P) communication with real-time messaging, file transfer, and cross-platform support for Android and iOS.

Homepage

License

unknown (license)

Dependencies

crypto, device_info_plus, file_picker, flutter, image_picker, path_provider, permission_handler, plugin_platform_interface

More

Packages that depend on wifi_direct_plugin

Packages that implement wifi_direct_plugin