rajath_pai

DiscoveryPage

Aug 4th, 2021
823
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import 'dart:async';
  2.  
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
  5.  
  6. import './BluetoothDeviceListEntry.dart';
  7.  
  8. class DiscoveryPage extends StatefulWidget {
  9.   /// If true, discovery starts on page start, otherwise user must press action button.
  10.   final bool start;
  11.  
  12.   const DiscoveryPage({this.start = true});
  13.  
  14.   @override
  15.   _DiscoveryPage createState() => new _DiscoveryPage();
  16. }
  17.  
  18. class _DiscoveryPage extends State<DiscoveryPage> {
  19.   StreamSubscription<BluetoothDiscoveryResult>? _streamSubscription;
  20.   List<BluetoothDiscoveryResult> results =
  21.       List<BluetoothDiscoveryResult>.empty(growable: true);
  22.   bool isDiscovering = false;
  23.  
  24.   _DiscoveryPage();
  25.  
  26.   @override
  27.   void initState() {
  28.     super.initState();
  29.  
  30.     isDiscovering = widget.start;
  31.     if (isDiscovering) {
  32.       _startDiscovery();
  33.     }
  34.   }
  35.  
  36.   void _restartDiscovery() {
  37.     setState(() {
  38.       results.clear();
  39.       isDiscovering = true;
  40.     });
  41.  
  42.     _startDiscovery();
  43.   }
  44.  
  45.   void _startDiscovery() {
  46.     _streamSubscription =
  47.         FlutterBluetoothSerial.instance.startDiscovery().listen((r) {
  48.       setState(() {
  49.         final existingIndex = results.indexWhere(
  50.             (element) => element.device.address == r.device.address);
  51.         if (existingIndex >= 0)
  52.           results[existingIndex] = r;
  53.         else
  54.           results.add(r);
  55.       });
  56.     });
  57.  
  58.     _streamSubscription!.onDone(() {
  59.       setState(() {
  60.         isDiscovering = false;
  61.       });
  62.     });
  63.   }
  64.  
  65.   // @TODO . One day there should be `_pairDevice` on long tap on something... ;)
  66.  
  67.   @override
  68.   void dispose() {
  69.     // Avoid memory leak (`setState` after dispose) and cancel discovery
  70.     _streamSubscription?.cancel();
  71.  
  72.     super.dispose();
  73.   }
  74.  
  75.   @override
  76.   Widget build(BuildContext context) {
  77.     return Scaffold(
  78.       appBar: AppBar(
  79.         title: isDiscovering
  80.             ? Text('Discovering devices')
  81.             : Text('Discovered devices'),
  82.         actions: <Widget>[
  83.           isDiscovering
  84.               ? FittedBox(
  85.                   child: Container(
  86.                     margin: new EdgeInsets.all(16.0),
  87.                     child: CircularProgressIndicator(
  88.                       valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
  89.                     ),
  90.                   ),
  91.                 )
  92.               : IconButton(
  93.                   icon: Icon(Icons.replay),
  94.                   onPressed: _restartDiscovery,
  95.                 )
  96.         ],
  97.       ),
  98.       body: ListView.builder(
  99.         itemCount: results.length,
  100.         itemBuilder: (BuildContext context, index) {
  101.           BluetoothDiscoveryResult result = results[index];
  102.           final device = result.device;
  103.           final address = device.address;
  104.           return BluetoothDeviceListEntry(
  105.             device: device,
  106.             rssi: result.rssi,
  107.             onTap: () {
  108.               Navigator.of(context).pop(result.device);
  109.             },
  110.             onLongPress: () async {
  111.               try {
  112.                 bool bonded = false;
  113.                 if (device.isBonded) {
  114.                   print('Unbonding from ${device.address}...');
  115.                   await FlutterBluetoothSerial.instance
  116.                       .removeDeviceBondWithAddress(address);
  117.                   print('Unbonding from ${device.address} has succed');
  118.                 } else {
  119.                   print('Bonding with ${device.address}...');
  120.                   bonded = (await FlutterBluetoothSerial.instance
  121.                       .bondDeviceAtAddress(address))!;
  122.                   print(
  123.                       'Bonding with ${device.address} has ${bonded ? 'succed' : 'failed'}.');
  124.                 }
  125.                 setState(() {
  126.                   results[results.indexOf(result)] = BluetoothDiscoveryResult(
  127.                       device: BluetoothDevice(
  128.                         name: device.name ?? '',
  129.                         address: address,
  130.                         type: device.type,
  131.                         bondState: bonded
  132.                             ? BluetoothBondState.bonded
  133.                             : BluetoothBondState.none,
  134.                       ),
  135.                       rssi: result.rssi);
  136.                 });
  137.               } catch (ex) {
  138.                 showDialog(
  139.                   context: context,
  140.                   builder: (BuildContext context) {
  141.                     return AlertDialog(
  142.                       title: const Text('Error occured while bonding'),
  143.                       content: Text("${ex.toString()}"),
  144.                       actions: <Widget>[
  145.                         new TextButton(
  146.                           child: new Text("Close"),
  147.                           onPressed: () {
  148.                             Navigator.of(context).pop();
  149.                           },
  150.                         ),
  151.                       ],
  152.                     );
  153.                   },
  154.                 );
  155.               }
  156.             },
  157.           );
  158.         },
  159.       ),
  160.     );
  161.   }
  162. }
RAW Paste Data