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

outdated

A Flutter BLE plugin, based on RxAndroidBle and RxBluetoothKit.

example/lib/main.dart

import 'dart:convert';

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter Rx BLE example'),
        ),
        body: MyApp(),
      ),
    ),
  );
}

class YesNoDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Location Permission Required'),
      content: Text(
        "This app needs location permission in order to access Bluetooth.\n"
        "Continue?",
      ),
      actions: <Widget>[
        SimpleDialogOption(
          child: Text(
            "NO",
            style: TextStyle(
              color: Colors.red,
              fontWeight: FontWeight.bold,
            ),
          ),
          onPressed: () {
            Navigator.of(context).pop(false);
          },
        ),
        SimpleDialogOption(
          child: Text(
            "YES",
            style: TextStyle(
              color: Colors.blue,
              fontWeight: FontWeight.bold,
            ),
          ),
          onPressed: () {
            Navigator.of(context).pop(true);
          },
        )
      ],
    );
  }
}

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

class _MyAppState extends State<MyApp> {
  var returnValue;
  Exception returnError;
  final results = <String, ScanResult>{};
  final uuidControl = TextEditingController(
    text: "0000ee09-0000-1000-8000-00805f9b34fb",
  );
  final mtuControl = TextEditingController();
  final writeCharValueControl = TextEditingController();
  String macAddress;
  var connectionState = BleConnectionState.disconnected;

  Function wrapCall(Function fn) {
    return () async {
      var value;
      setState(() {
        returnError = returnValue = null;
      });
      try {
        value = await fn();
      } catch (e, trace) {
        print('returnError: $e\n$trace');
        if (!mounted) return;
        setState(() {
          returnError = e;
        });
        return;
      }
      print('returnValue: $value');
      if (!mounted) return;
      setState(() {
        returnValue = value;
      });
    };
  }

  Future<void> requestAccessRationale() async {
    return await RxBle.requestAccess(
      showRationale: () async {
        return await showDialog(
              context: context,
              builder: (context) => YesNoDialog(),
            ) ??
            false;
      },
    );
  }

  Future<void> startScan() async {
    await for (final scanResult in RxBle.startScan()) {
      results[scanResult.macAddress] = scanResult;
      if (!mounted) return;
      setState(() {
        returnValue = JsonEncoder.withIndent(" " * 2, (o) {
          if (o is ScanResult) {
            return o.toString();
          } else {
            return o;
          }
        }).convert(results);
      });
    }
  }

  Future<void> readChar() async {
    final value = await RxBle.readChar(macAddress, uuidControl.text);
    return value.toString() + "\n\n" + utf8.decode(value);
  }

  Future<void> writeChar() async {
    return await RxBle.writeChar(
      macAddress,
      uuidControl.text,
      utf8.encode(writeCharValueControl.text),
    );
  }

  Future<void> requestMtu() async {
    return await RxBle.requestMtu(macAddress, int.parse(mtuControl.text));
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: ListView(
        children: <Widget>[
          Text("Return Value:"),
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Container(
              color: Colors.black,
              child: Text(
                "$returnValue",
                style: TextStyle(
                  fontFamily: 'DejaVuSansMono',
                  color: Colors.white,
                ),
              ),
            ),
          ),
          Divider(),
          Text("Error:"),
          SingleChildScrollView(
            scrollDirection: Axis.horizontal,
            child: Container(
              color: Colors.black,
              child: Text(
                "$returnError",
                style: TextStyle(
                  fontFamily: 'DejaVuSansMono',
                  color: Colors.white,
                ),
              ),
            ),
          ),
          Divider(),
          Container(
            color: Colors.black,
            child: Text(
              connectionState.toString(),
              style: TextStyle(
                fontFamily: 'DejaVuSansMono',
                color: Colors.white,
              ),
            ),
          ),
          Divider(),
          RaisedButton(
            child: Text(
              "requestAccess()",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(RxBle.requestAccess),
          ),
          RaisedButton(
            child: Text(
              "requestAccess(showRationale)",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(requestAccessRationale),
          ),
          RaisedButton(
            child: Text(
              "hasAccess()",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(RxBle.hasAccess),
          ),
          RaisedButton(
            child: Text(
              "openAppSettings()",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(RxBle.openAppSettings),
          ),
          Divider(),
          RaisedButton(
            child: Text(
              "startScan()",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(startScan),
          ),
          RaisedButton(
            child: Text(
              "stopScan()",
              style: TextStyle(fontFamily: 'DejaVuSansMono'),
            ),
            onPressed: wrapCall(RxBle.stopScan),
          ),
          Divider(),
          if (results.isEmpty) Text('Start scanning to connect to a device'),
          for (final scanResult in results.values)
            RaisedButton(
              child: Text(
                "conenct(${scanResult.macAddress})",
                style: TextStyle(fontFamily: 'DejaVuSansMono'),
              ),
              onPressed: wrapCall(() async {
                await RxBle.stopScan();
                setState(() {
                  macAddress = scanResult.macAddress;
                });
                await for (final state in RxBle.connect(macAddress)) {
                  print("device state: $state");
                  if (!mounted) return;
                  setState(() {
                    connectionState = state;
                  });
                }
              }),
            ),
          Divider(),
          if (connectionState == BleConnectionState.connected) ...[
            RaisedButton(
              child: Text(
                "disconnect()",
                style: TextStyle(fontFamily: 'DejaVuSansMono'),
              ),
              onPressed: wrapCall(() async {
                await RxBle.disconnect();
              }),
            ),
            TextField(
              controller: uuidControl,
              decoration: InputDecoration(
                labelText: "uuid",
              ),
            ),
            RaisedButton(
              child: Text(
                "device.readChar()",
                style: TextStyle(fontFamily: 'DejaVuSansMono'),
              ),
              onPressed: wrapCall(readChar),
            ),
            TextField(
              controller: writeCharValueControl,
              decoration: InputDecoration(
                labelText: "writeChar value",
              ),
            ),
            RaisedButton(
              child: Text(
                "device.writeChar()",
                style: TextStyle(fontFamily: 'DejaVuSansMono'),
              ),
              onPressed: wrapCall(writeChar),
            ),
            TextField(
              controller: mtuControl,
              decoration: InputDecoration(
                labelText: "mtu",
              ),
            ),
            RaisedButton(
              child: Text(
                "device.requestMtu()",
                style: TextStyle(fontFamily: 'DejaVuSansMono'),
              ),
              onPressed: wrapCall(requestMtu),
            ),
          ] else
            Text("Connect to a device to perform GATT operations."),
        ],
      ),
    );
  }
}
8
likes
0
pub points
31%
popularity

Publisher

unverified uploader

A Flutter BLE plugin, based on RxAndroidBle and RxBluetoothKit.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

flutter, method_call_dispatcher

More

Packages that depend on rx_ble