skip to Main Content

I have function that reads BLE characteristics data (numers in List type). I want to run it asynchronously after widget is built. I need access to context variable (Because of Provider – state management library). Data gathered from device are coming in long period of time (tens of minutes, usually 20-30 minutes). I want to fill List with this data, but need this, before described, functionality of this async function. How can I do that? Data will asyncchronously be read and will be “coming” to UI (will be presented in a ListView, which I already have). I am using latest Flutter.

Currently I read data by clicking ElevatedButton (onPressed), but I need before mentioned async functions working in a loop.

      onPressed: () async =>
                {
                result = await  inter.readCharacteristic(characteristic),
                print(new String.fromCharCodes(result)),
                },

I need to check BLE characteristics every 10 sec.

Where should I place such function?

2

Answers


  1. Are you using any state management library ?

    If so then you can start your async function at the start of your build method by doing something like Future(() { myAsyncfunc(); });, update state in that func and use state management library to trigger widget re-build. Although I am sure you can come up with a better logic to handle this.

    If no, then you can try passing buildContext and setState to that async function and call setState from that func. Make sure to check for context.mounted before calling setState.

    Login or Signup to reply.
  2. Simplest answer I can give you right now is using a combination of a StatefulWidget and Timer.periodic to periodically read the BLE characteristics and update your UI.

    Here’s an example implementation:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:your_package_name_here/your_ble_library.dart';
    import 'package:provider/provider.dart';
    
    class MyWidget extends StatefulWidget {
      const MyWidget({Key? key}) : super(key: key);
    
      @override
      _MyWidgetState createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      List<int> characteristicData = [];
    
      late Timer timer;
    
      @override
      void initState() {
        super.initState();
    
        // Start the timer to read characteristics every 10 seconds
        timer = Timer.periodic(Duration(seconds: 10), (Timer t) async {
          // Get the BLE interface from the Provider
          final inter = Provider.of<BLEInterface>(context, listen: false);
    
          // Read the characteristics
          final result = await inter.readCharacteristic(characteristic);
    
          // Update the UI with the new data
          setState(() {
            characteristicData.addAll(result);
          });
        });
      }
    
      @override
      void dispose() {
        // Cancel the timer when the widget is disposed
        timer.cancel();
    
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return ListView.builder(
          itemCount: characteristicData.length,
          itemBuilder: (BuildContext context, int index) {
            return Text(characteristicData[index].toString());
          },
        );
      }
    }
    

    Here, we use the initState method to start a Timer that reads the BLE characteristics every 10 seconds. We also use setState to update the UI with the new data.

    In the dispose method, we cancel the timer to avoid memory leaks.

    You can place this MyWidget widget wherever you need it in your app, and use it like any other widget.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search