flutter_p2p_plus 1.0.2 copy "flutter_p2p_plus: ^1.0.2" to clipboard
flutter_p2p_plus: ^1.0.2 copied to clipboard

A WiFi Direct Plugin for Flutter. This Plugin uses the native WiFi P2P API of Android.

example/lib/main.dart

/*
 * This file is part of the flutter_p2p package.
 *
 * Copyright 2019 by Julian Finkler <julian@mintware.de>
 *
 * For the full copyright and license information, please read the LICENSE
 * file that was distributed with this source code.
 *
 */

import 'dart:convert';

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

import 'package:flutter_p2p_plus/flutter_p2p_plus.dart';
import 'package:flutter_p2p_plus/protos/protos.pb.dart';
import 'package:permission_handler/permission_handler.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  var _deviceAddress = "";
  var _isConnected = false;
  var _isHost = false;
  var _isOpen = false;

  P2pSocket? _socket;
  List<WifiP2pDevice> devices = [];
  final List<StreamSubscription> _subscriptions = [];

  @override
  void initState() {
    super.initState();
    _register();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    FlutterP2pPlus.removeGroup();
    for (var element in _subscriptions) {
      element.cancel();
    }
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _register();
    } else if (state == AppLifecycleState.paused) {
      _unregister();
    }
  }

  void _register() async {
    await Permission.location.request();

    if (!await _checkPermission()) {
      return;
    }
    _subscriptions.add(FlutterP2pPlus.wifiEvents.stateChange!.listen((change) {
      debugPrint("stateChange: ${change.isEnabled}");
    }));

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

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

    _subscriptions.add(FlutterP2pPlus.wifiEvents.discoveryChange!.listen((change) {
      debugPrint("discoveryStateChange: ${change.isDiscovering}");
    }));

    _subscriptions.add(FlutterP2pPlus.wifiEvents.peersChange!.listen((change) {
      debugPrint("peersChange: ${change.devices.length}");
      for (var device in change.devices) {
        debugPrint("device: ${device.deviceName} / ${device.deviceAddress}");
      }

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

    FlutterP2pPlus.register();
  }

  void _unregister() {
    for (var subscription in _subscriptions) {
      subscription.cancel();
    }
    FlutterP2pPlus.unregister();
  }

  void _openPortAndAccept(int port) async {
    if (!_isOpen) {
      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");
    }
  }

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

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

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

    debugPrint("_connectToPort done");
  }

  Future<bool> _checkPermission() async {
    // if (!await FlutterP2pPlus?.isLocationPermissionGranted()) {
    //   await FlutterP2pPlus.requestLocationPermission();
    //   return false;
    // }
    if (await Permission.location.status.isDenied) {
      return false;
    }
    return true;
  }

  Future<bool?> _disconnect() async {
    bool? result = await FlutterP2pPlus.removeGroup();
    _unregister();
    _socket = null;
    if ((result ?? false)) _isOpen = false;
    return result;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('Plugin example app 2'),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            ListTile(
              title: const Text("Registration"),
              subtitle: Text("P2P Registration"),
              onTap: () async {
                await FlutterP2pPlus.register();
              },
            ),
            ListTile(
              title: const Text("Connection State"),
              subtitle: Text(_isConnected ? "Connected: ${_isHost ? "Host" : "Client"}" : "Disconnected"),
            ),
            const Divider(),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                "Controller",
                style: Theme.of(context).textTheme.headline5,
              ),
            ),
            IntrinsicHeight(
              child: Row(
                children: [
                  Expanded(
                    child: ListTile(
                      title: const Text("Discover Devices"),
                      onTap: () async {
                        if (!_isConnected) {
                          await FlutterP2pPlus.discoverDevices();
                        } else {
                          return;
                        }
                      },
                    ),
                  ),
                  VerticalDivider(
                    color: Colors.grey,
                  ),
                  Expanded(
                    child: ListTile(
                      title: const Text("Stop Discover Devices"),
                      onTap: () async {
                        FlutterP2pPlus.stopDiscoverDevices();
                      },
                    ),
                  ),
                ],
              ),
            ),
            const Divider(),
            ListTile(
              title: const Text("Open and accept data from port 8000"),
              subtitle: _isConnected ? const Text("Active") : const Text("Disable"),
              onTap: _isConnected && _isHost ? () => _openPortAndAccept(8000) : null,
            ),
            const Divider(),
            ListTile(
              title: const Text("Connect to port 8000"),
              subtitle: const Text("This is able to only Client"),
              onTap: _isConnected && !_isHost ? () => _connectToPort(8000) : null,
            ),
            const Divider(),
            ListTile(
              title: const Text("Send hello world"),
              onTap: _isConnected ? () async => await _socket?.writeString("Hello World") : null,
            ),
            const Divider(),
            ListTile(
              title: const Text("Disconnect"),
              onTap: _isConnected ? () async => await _disconnect() : null,
            ),
            const Divider(),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text(
                "Device List",
                style: Theme.of(context).textTheme.headline5,
              ),
            ),
            Expanded(
              child: ListView(
                children: devices.map((d) {
                  return ListTile(
                    title: Text(d.deviceName),
                    subtitle: Text(d.deviceAddress),
                    onTap: () async {
                      debugPrint("${_isConnected ? "Disconnect" : "Connect"} to device: $_deviceAddress");
                      if (_isConnected) {
                        await FlutterP2pPlus.cancelConnect(d);
                      } else {
                        var result = (await FlutterP2pPlus.connect(d) ?? false);
                        print("[connect] reault: $result");
                        if (result) {
                          _isConnected = true;
                        }
                        setState(() {});
                      }
                    },
                  );
                }).toList(),
              ),
            ),
          ],
        ),
      ),
    );
  }

  snackBar(String text) {
    ScaffoldMessenger.of(_scaffoldKey.currentContext!).showSnackBar(
      SnackBar(
        content: Text(text),
        duration: const Duration(seconds: 2),
      ),
    );
  }
}
7
likes
60
points
35
downloads

Publisher

unverified uploader

Weekly Downloads

A WiFi Direct Plugin for Flutter. This Plugin uses the native WiFi P2P API of Android.

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

flutter, flutter_web_plugins, protobuf

More

Packages that depend on flutter_p2p_plus

Packages that implement flutter_p2p_plus