Flutter: извлеките функциональность BLE в класс - PullRequest
0 голосов
/ 20 июня 2020

Я использую библиотеку Flutter_blue (https://pub.dev/packages/flutter_blue) для функциональности BLE во Flutter и хочу упаковать все функции BLE в отдельный класс.

Проблема в том, как передать функцию " handleData ", который отвечает за изменение состояния этого класса. Создание экземпляра класса внутри initState нарушает подключение BLE, поскольку он каждый раз пытается сканировать устройства и обнаруживать новые службы. Но я не нашел способа найти устройства и службы до initState () и иметь возможность ссылаться на метод handleData ().

main.dart

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

Future<void> main() async {
  runApp(MainScreen());
}

class MainScreen extends StatefulWidget {
  @override
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  FlutterBle connection;
  String kmph;
  int rpm;

  void handleData(String receivedStr) {
    setState(() {
      this.kmph = receivedStr;
    });
  }

  @override
  void initState() {
    super.initState();
    // instanstiating this class on each init state breaks the BLE connection
    connection = FlutterBle(handleData);
    connection.readData();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BLE test',
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: new SafeArea(
            child: Center(
          child: Text("$kmph"),
        )),
      ),
      theme: ThemeData.dark(),
    );
  }
}

и класс BLE или flutterBLE.dart

import 'dart:async';
import 'dart:convert';
import 'package:flutter_blue/flutter_blue.dart';

class FlutterBle {
  static const TARGET_DEVICE_NAME = "ESP32";
  static const SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b";
  static const CHARACTERISTIC_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8";

  StreamSubscription<ScanResult> scanSubScription;
  BluetoothDevice targetDevice;
  BluetoothCharacteristic targetCharacteristic;

  Function wigetFunc;

  FlutterBlue flutterBlue = FlutterBlue.instance;

  FlutterBle(someFunction) {
    wigetFunc = someFunction;
    startScan();
  }

  startScan() {
    scanSubScription = flutterBlue.scan().listen((scanResult) {
      if (scanResult.device.name == TARGET_DEVICE_NAME) {
        print('DEVICE found');
        stopScan();
        targetDevice = scanResult.device;
        connectToDevice();
      }
    }, onDone: () => stopScan());
  }

  stopScan() {
    scanSubScription?.cancel();
    scanSubScription = null;
  }

  connectToDevice() async {
    if (targetDevice == null) return;

    await targetDevice.connect();
    print('DEVICE CONNECTED');
    discoverServices();
  }

  disconnectFromDevice() {
    if (targetDevice == null) return;

    targetDevice.disconnect();
  }

  discoverServices() async {
    if (targetDevice == null) return;

    List<BluetoothService> services = await targetDevice.discoverServices();
    services.forEach((service) {
      // do something with service
      if (service.uuid.toString() == SERVICE_UUID) {
        service.characteristics.forEach((characteristic) {
          if (characteristic.uuid.toString() == CHARACTERISTIC_UUID) {
            targetCharacteristic = characteristic;
            readData();
          }
        });
      }
    });
  }

  readData() {
    targetCharacteristic.value.listen((value) {
      String receivedStr = ascii.decode(value);
      // this function should call handleData and set state.
      wigetFunc(receivedStr);
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...