flutter_p2p 0.1.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 82

GitHub license Pub

flutter_p2p #

A Wi-Fi Direct Plugin for Flutter.

This plugin is in alpha and only supports android at the moment.

Getting Started #

Required permissions #

Put this into your 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"/>

Request permission #

In order to scan for devices and connect to devices you need to ask for the location Permission

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

Register / unregister from WiFi events #

To receive notifications for connection changes or device changes (peers discovered etc.) you have to subscribe to the wifiEvents and register the plugin to the native events.

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) {
    // Stop handling events when the app doesn't run to prevent battery draining

    if (state == AppLifecycleState.resumed) {
      _register();
    } else if (state == AppLifecycleState.paused) {
      _unregister();
    }
  }

  List<StreamSubscription> _subscriptions = [];

  void _register() async {
    if (!await _checkPermission()) {
      return;
    }
    _subscriptions.add(FlutterP2p.wifiEvents.stateChange.listen((change) {
      // Handle wifi state change
    }));

    _subscriptions.add(FlutterP2p.wifiEvents.connectionChange.listen((change) {
      // Handle changes of the connection
    }));

    _subscriptions.add(FlutterP2p.wifiEvents.thisDeviceChange.listen((change) {
      // Handle changes of this device
    }));

    _subscriptions.add(FlutterP2p.wifiEvents.peersChange.listen((change) {
      // Handle discovered peers
    }));

    _subscriptions.add(FlutterP2p.wifiEvents.discoveryChange.listen((change) {
      // Handle discovery state changes
    }));

    FlutterP2p.register();  // Register to the native events which are send to the streams above
  }

  void _unregister() {
    _subscriptions.forEach((subscription) => subscription.cancel()); // Cancel subscriptions
    FlutterP2p.unregister(); // Unregister from native events
  }
}

Discover devices #

After you subscribed to the events you only need to call the FlutterP2p.discoverDevices() method.


List<WifiP2pDevice> _peers = [];

void _register() async {

  /// ...

  _subscriptions.add(FlutterP2p.wifiEvents.peersChange.listen((change) {
    setState(() {
      _peers = change.devices;
    });
  }));

  /// ...
}

void _discover() {
  FlutterP2p.discoverDevices();
}

Connect to a device #

Call FlutterP2p.connect(device); and listen to the FlutterP2p.wifiEvents.connectionChange


 bool _isConnected = false;
 bool _isHost = false;
 String _deviceAddress = "";

 void _register() async {
    // ...

    _subscriptions.add(FlutterP2p.wifiEvents.connectionChange.listen((change) {
      setState(() {
        _isConnected = change.networkInfo.isConnected;
        _isHost = change.wifiP2pInfo.isGroupOwner;
        _deviceAddress = change.wifiP2pInfo.groupOwnerAddress;
      });
    }));

    // ...
  }

Disconnect from current P2P group #

Call FlutterP2p.removeGroup()

 void _disconnect() async {
   FlutterP2p.removeGroup();
 }

Transferring data between devices #

After you are connected to a device you can transfer data async in both directions (client -> host, host -> client).

On the host:

  // Open a port and create a socket

  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) {
        _showSnackBar("Data Received: $buffer");
        buffer = "";
      }
    });

    // Write data to the client using the _socket.write(UInt8List) or `_socket.writeString("Hello")` method


    print("_openPort done");

    // accept a connection on the created socket
    await FlutterP2p.acceptPort(port);
    print("_accept done");
  }

On the client:

  // Connect to the port and create a socket

  P2pSocket _socket;
  _connectToPort(int port) async {
    var socket = await FlutterP2p.connectToHost(
      _deviceAddress, // see above `Connect to a device`
      port,
      timeout: 100000, // timeout in milliseconds (default 500)
    );

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

    var buffer = "";
    socket.inputStream.listen((data) {
      var msg = String.fromCharCodes(data.data);
      buffer += msg;

      if (data.dataAvailable == 0) {
        _showSnackBar("Received from host: $buffer");
        buffer = "";
      }
    });

    // Write data to the host using the _socket.write(UInt8List) or `_socket.writeString("Hello")` method

    print("_connectToPort done");
  }

Next version #

No changes yet

0.1.1 #

Optimizations:

  • Set the minSdk Version to 16 to Support Android 4.1 and newer. Thanks to AbdulhakimZ PR#5

0.1.0 #

Features:

  • Added WifiP2pManager.removeGroup to be able to disconnect from the current group. Thanks to qwales1 PR#2
  • Added a listener for WIFI_P2P_DISCOVERY_CHANGED_ACTION for listening to discovery state changes group. Thanks to qwales1 PR#4

Optimizations:

  • Created a ResultActionListener which implements WifiP2pManager.ActionListener to remove duplicate code.

0.0.2 #

  • Applied pub.dev suggestions

0.0.1 #

  • Initial Release

example/README.md

flutter_p2p_example #

Demonstrates how to use the flutter_p2p plugin.

Getting Started #

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Use this package as a library

1. Depend on it

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


dependencies:
  flutter_p2p: ^0.1.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_p2p/flutter_p2p.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
64
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
82
Learn more about scoring.

We analyzed this package on Jan 19, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.4
  • Flutter: 1.12.13+hotfix.5

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
protobuf ^1.0.0 1.0.1
Transitive dependencies
collection 1.14.11 1.14.12
fixnum 0.10.11
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test