DEV Community

Julian Finkler
Julian Finkler

Posted on • Edited on

Flutter WiFi Direct Plugin

Hey,

I started working on a WiFi Direct (P2P) plugin for Flutter.

https://github.com/mintware-de/flutter_p2p

So far working (Android only at the moment):

  • Subscribe to WiFi Events
  • Discover devices
  • Connect to a device
  • Transfer data between the devices using web sockets and streams.

Feel free to collaborate 🙂

Top comments (14)

Collapse
 
hrihtik profile image
Hrithik-S

THIS IS MY CODE:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter_p2p/flutter_p2p.dart';
import 'package:flutter_p2p/gen/protos/protos.pb.dart';

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State 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 devices = [];

var _isConnected = false;
var _isHost = false;

List _subscriptions = [];

void _register() async {
if (!await _checkPermission()) {
return;
}
_subscriptions.add(FlutterP2p.wifiEvents.stateChange.listen((change) {
print("stateChange: ${change.isEnabled}");
}));

_subscriptions.add(FlutterP2p.wifiEvents.connectionChange.listen((change) {
  setState(() {
    _isConnected = change.networkInfo.isConnected;
    _isHost = change.wifiP2pInfo.isGroupOwner;
    _deviceAddress = change.wifiP2pInfo.groupOwnerAddress;
  });
  print(
      "connectionChange: ${change.wifiP2pInfo.isGroupOwner}, Connected: ${change.networkInfo.isConnected}");
}));

_subscriptions.add(FlutterP2p.wifiEvents.thisDeviceChange.listen((change) {
  print(
      "deviceChange: ${change.deviceName} / ${change.deviceAddress} / ${change.primaryDeviceType} / ${change.secondaryDeviceType} ${change.isGroupOwner ? 'GO' : '-GO'}");
}));

_subscriptions.add(FlutterP2p.wifiEvents.discoveryChange.listen((change) {
  print("discoveryStateChange: ${change.isDiscovering}");
}));

_subscriptions.add(FlutterP2p.wifiEvents.peersChange.listen((change) {
  print("peersChange: ${change.devices.length}");
  change.devices.forEach((device) {
    print("device: ${device.deviceName} / ${device.deviceAddress}");
  });

  setState(() {
    devices = change.devices;
  });
}));

FlutterP2p.register();
Enter fullscreen mode Exit fullscreen mode

}

void _unregister() {
_subscriptions.forEach((subscription) => subscription.cancel());
FlutterP2p.unregister();
}

P2pSocket _socket;
void _openPortAndAccept(int port) async {
var socket = await FlutterP2p.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: $buffer");
    socket.writeString("Successfully received: $buffer");
    buffer = "";
  }
});

print("_openPort done");

await FlutterP2p.acceptPort(port);
print("_accept done");
Enter fullscreen mode Exit fullscreen mode

}

var _deviceAddress = "";

_connectToPort(int port) async {
var socket = await FlutterP2p.connectToHost(
_deviceAddress,
port,
timeout: 100000,
);

setState(() {
  _socket = socket;
});

_socket.inputStream.listen((data) {
  var msg = utf8.decode(data.data);
  snackBar("Received from Host: $msg");
});

print("_connectToPort done");
Enter fullscreen mode Exit fullscreen mode

}

Future _checkPermission() async {
if (!await FlutterP2p.isLocationPermissionGranted()) {
await FlutterP2p.requestLocationPermission();
return false;
}
return true;
}

final _scaffoldKey = GlobalKey();

@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('Plugin example app 2'),
),
body: Column(
children: [
Text(_isConnected
? "Connected: ${_isHost ? "Host" : "Client"}"
: "Disconnected"),
RaisedButton(
onPressed: () => FlutterP2p.discoverDevices(),
child: Text("Discover Devices"),
),
RaisedButton(
onPressed:
_isConnected && _isHost ? () => _openPortAndAccept(8888) : null,
child: Text("Open and accept data from port 8888"),
),
RaisedButton(
onPressed: _isConnected ? () => _connectToPort(8888) : null,
child: Text("Connect to port 8888"),
),
RaisedButton(
onPressed: _socket != null
? () => _socket.writeString("Hello World")
: null,
child: Text("Send hello world"),
),
RaisedButton(
onPressed: _isConnected ? () => FlutterP2p.removeGroup() : null,
child: Text("Disconnect"),
),
Expanded(
child: ListView(
children: this.devices.map((d) {
return ListTile(
title: Text(d.deviceName),
subtitle: Text(d.deviceAddress),
onTap: () {
print(
"${_isConnected ? "Disconnect" : "Connect"} to device: $_deviceAddress");
return _isConnected
? FlutterP2p.cancelConnect(d)
: FlutterP2p.connect(d);
},
);
}).toList(),
),
),
],
),
);
}

snackBar(String text) {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text(text),
duration: Duration(seconds: 2),
),
);
}
}

ERROR OCCURED TO ME:

A problem occurred configuring project ':flutter_p2p'.

Could not resolve all artifacts for configuration ':flutter_p2p:classpath'.
Could not download kotlin-compiler-embeddable.jar (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.71)
> Could not get resource 'jcenter.bintray.com/org/jetbrains/...'.
> Premature end of Content-Length delimited message body (expected: 29106171; received: 27524912
Could not get unknown property 'android' for project ':flutter_p2p' of type org.gradle.api.Project.

Collapse
 
azadprajapat profile image
azad prajapat

Dear sir thank you for providing help on wifi direct and p2p connection . i have issue in transferring data like image videos and some else format over the socket basically how the data is going to be encoded and decoded at server and client side please help

Collapse
 
shivamshashank profile image
shivam-shashank

Can you please provide with sample code because discover devices showing empty List everytime.

Collapse
 
devtronic profile image
Julian Finkler

A working sample is contained in the README. Are the other devices "visible"?

Collapse
 
shivamshashank profile image
shivam-shashank

on tapping discover devices it is showing empty list of wifi networks....
Plz see to it.

Collapse
 
abdulhakimz profile image
AbdulhakimZ

I've seen it. Very nice Library thank you. But the minimum API level that it supports is API level 23. What about for API level below 23?

Collapse
 
devtronic profile image
Julian Finkler

Thanks for your reply. Probably this was the default minimum SDK as I started working on this lib. Let me take a look if I can downgrade the version :-)

Collapse
 
abdulhakimz profile image
AbdulhakimZ

I have modified it to support android version starting from 4.1, Please accept the pull request and modify the library on pub.dev

Collapse
 
vsstechhacks profile image
vsstechhacks

how I can send and receive files like images, docs, etc. using p2p

Collapse
 
devtronic profile image
Julian Finkler

Simply follow the instructions in the README github.com/mintware-de/flutter_p2p

  1. Scan for other devices
  2. Connect to the device
  3. Open a socket and send binary data through it
Collapse
 
namchuai profile image
NamH

AFAIK, iOS does not support Wi-Fi direct. Link: forums.developer.apple.com/thread/...

Collapse
 
jaykishnk profile image
Jaykishan Khemani

Hello Sir , i was working with your package provided on flutterp2p i was having a query that is can i send files (jpg , png , pdf etc.) using this package. please help
thank you

Collapse
 
hrihtik profile image
Hrithik-S • Edited

please give solution to me , my source code is below

Collapse
 
manditjyotiborah profile image
ManditjyotiBorah

Sir, please provide a manual how to use the plugin .