Giter Club home page Giter Club logo

flutter_reactive_ble's People

Contributors

danielroek avatar danielstuart14 avatar dnfield avatar ened avatar epietrowicz avatar jalpedersen avatar jamesblasco avatar jason-simmons avatar jobfeikens avatar jonahwilliams avatar keenranger avatar ky1vstar avatar miguelcmedeiros avatar pieteraelse avatar remonh87 avatar rexios80 avatar robert-ancell avatar rtgrv avatar safield avatar spkersten avatar srawlins avatar swift-kim avatar taym95 avatar vbuberen avatar vsxed avatar wcoder avatar werediver avatar xvrh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter_reactive_ble's Issues

Example app crashes when clearing GATT cache (on Android)

When I try to use the clearGATTcache method, using the edited example app on Android, the app crashes on a RX error that I think comes from the library:

2020-01-07 13:46:56.795 26969-27186/com.signify.hue.reactivebleexample E/AndroidRuntime: FATAL EXCEPTION: RxComputationThreadPool-6
Process: com.signify.hue.reactivebleexample, PID: 26969
io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: RxComputationThreadPool-6
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)

Throw exception on subscription to non-readable characteristic

We spent a long time troubleshooting why we stopped receiving data from the BLE device. Turned out to be that a firmware update erroneously changed the characteristic to "write" only. Perhaps trying to subscribe to a characteristic that didn't allow reading should throw an exception because it cannot possibly ever actually receive any data.

Error while scanning for devices: Location Permission missing

Describe the bug
Get the following error when trying to scan:

E/flutter: [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Exception: GenericFailure(code: ScanFailure.unknown, message: "Location Permission missing (code 3)")

To Reproduce
Steps to reproduce the behavior:

  1. Installed flutter_reactive_ble: ^2.0.0
  2. Implemented bleScanner
  3. scannerObj.startScan();

Expected behaviour
Request for ACCESS_FINE_LOCATION permission

Smartphone / tablet

  • Device: Samsung A5 2017
  • OS: Android 8.0.0
  • Package version: 2.0.0

Peripheral device

  • Vendor, model: raspberry pi
  • Does it run a custom firmware / software: go-ble

Additional context
Setup is working with flutter_blue.

Restarting/Refreshing in dev mode makes it crash with alreadyInitialized error on iOS

I have tried this both with the example app and my own app with the same result. Both simulator (iOS) and a device (iPhone 8).

Using the restart command for flutter in dev mode makes this lib crash with the following output

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: PlatformException(alreadyInitialized, already initialized, null)
#0      StandardMethodCodec.decodeEnvelope 
package:flutter/…/services/message_codecs.dart:569
#1      MethodChannel._invokeMethod 
package:flutter/…/services/platform_channel.dart:156
<asynchronous suspension>
#2      MethodChannel.invokeMethod 
package:flutter/…/services/platform_channel.dart:329
#3      FlutterReactiveBle.initialize 
package:flutter_reactive_ble/src/reactive_ble.dart:90
#4      FlutterReactiveBle._trackStatus 
package:flutter_reactive_ble/src/reactive_ble.dart:55
#5      new FlutterReactiveBle._ 
package:flutter_reactive_ble/src/reactive_ble.dart:28
#6      FlutterReactiveBle._sharedInstance 
package:flutter_reactive_ble/src/reactive_ble.dart:23
#7      FlutterReactiveBle._sharedInstance 
package:flutter_reactive_ble/src/reactive_ble.dart:23
#8      new FlutterReactiveBle (package:flutter_reactive_ble/src/reactive_ble.dart:25:3<…>

This is especially annoying during development as it hangs the whole simulator/device and the app needs to be recompiled and launched again. It does not happen when just using the hot reload functionality.

This shouldn't be a problem in production mode due to the fact that there is no way to "refresh" the app instance. Have not tried if it all applies on Android as well.

Small inconsistency between iOS and Android with short/long UUID

Full disclosure: I don't really understand what I'm talking about :-) I'm just reporting this in case it helps someone.

Describe the bug
I noticed a small difference between Android and iOS when registering a characteristic for Notification (subscribeToCharacteristic).

My device "somehow" uses "short UUID" (16 bits) but I was using the long form (128bits) in my code (QualifiedCharacteristic).
It works for Read and Write on both Android and iOS. But for "Subscribe" it only works for Android.

On iOS I had no error but I never received the data.

With the short Uuid, the notification worked on both platform.

Expected behavior
It should work the same on both Android and iOS. The iOS code should probably map the short Uuid (sent by the device?) to the long form registered on the phone?

Smartphone / tablet

  • Device: iPhone 11 and Moto G5
  • OS: iOS 13, Android 8.1
  • Package version: 2.2.0

Peripheral device

  • Vendor, model: ESP32
  • Does it run a custom firmware / software: custom firmware based on ESP-IDF v4

minSdk API lvl 24 as a lib requirement

Describe the bug
The libs minSdk requirement for Android should be lowered, since BLE has been introduced in API level 18/19, but the library is requiring API level 24

To Reproduce
Try to build the example app with minSdk set to API lvl 19

Expected behavior
Should be building while i drink my coffee

  • I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above

Smartphone / tablet

  • Device: Nexus 4, 4.4 Kitkat

Peripheral device

Additional context

iOS always sends the same command, Android works OK

Following my problems reported in #95 my code works for Android, but in iOS it sends the first command correctly, then every following command is just the first command repeated. At the end of my connect routine, I need to get different state information from the bluetooth device so I send a set of commands:

void sendInitialCommands() async {
    print("====sendInitialCommands");
    sendString('y');
    sendString('x');
    sendString('h');
    print("=======================");
  }

  sendString(String dataStr) async {
    List<int> dataOut = asciiCodec.encode(dataStr);
    print("Sending " + asciiCodec.decode(dataOut));
    await _ble.writeCharacteristicWithResponse(txCharacteristic, value: dataOut);
  }

on Android I correctly get answers to those 3 commands:

D/BluetoothGatt(15802): connect() - device: A4:CF:12:78:10:3E, auto: true
D/BluetoothGatt(15802): registerApp()
D/BluetoothGatt(15802): registerApp() - UUID=18f9a898-54d2-4fcf-9960-29562c60ef2e
D/BluetoothGatt(15802): onClientRegistered() - status=0 clientIf=8
I/flutter (15802): ====SendInitialCommands
I/flutter (15802): Sending y
I/flutter (15802): Sending x
I/flutter (15802): Sending h
/flutter (15802): =======================
D/BluetoothGatt(15802): onClientConnectionState() - status=0 clientIf=8 device=A4:CF:12:78:10:3E
D/BluetoothGatt(15802): discoverServices() - device: A4:CF:12:78:10:3E
I/flutter (15802): connectToAdvertisingDevice error: TimeoutException after 0:00:06.000000: Future not completed
D/BluetoothGatt(15802): onConnectionUpdated() - Device=A4:CF:12:78:10:3E interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt(15802): onSearchComplete() = Device=A4:CF:12:78:10:3E Status=0
D/BluetoothGatt(15802): onConnectionUpdated() - Device=A4:CF:12:78:10:3E interval=30 latency=0 timeout=500 status=0
D/BluetoothGatt(15802): setCharacteristicNotification() - uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e enable: true
I/flutter (15802): Received: [y 10]
I/flutter (15802): Received: [x 8]
I/flutter (15802): Received: [h 160]

However, on iOS it reports the first command being correctly sent but subsequent commands only re-trigger the first command. I can see on the bluetooth device that the same command is transmitted repeatedly. Also, the Gatt reporting shown above for Android is missing on iOS.

flutter: Status update at: 2020-08-11T17:34:04.876624 to: ConnectionStateUpdate(deviceId: 0E76782B-8B93-89F0-B597-8F2963FAE171, connectionState: DeviceConnectionState.connected, error: null)
flutter: ====SendInitialCommands
flutter: Sending y
flutter: Sending x
flutter: Sending h
flutter: =======================
flutter: Received: [y 10]
flutter: Received: [y 10]
flutter: Received: [y 10]

How can I debug what is happening within
await _ble.writeCharacteristicWithResponse(txCharacteristic, value: dataOut);
or what am I doing wrong?

Does it work in a separate dart isolate?

I have a use case where I need to do a scan periodically in a separate isolate and was wondering if flutter_reactive_ble is capable of doing that. Recently flutter_isolate stopped working with all the plugins I'm using so I guess something changed in flutter itself and am looking for something that is capable of running in a different isolate.
Thanks

iOS render overflow in example Scan for devices Enter UUID text

Firstly very many thanks for a wonderfully presented, designed and documented library.

Describe the bug
On iPhones with screen size 750 x 1334 pixels the example Scan for Devices screen has a line of text:
Enter a UUID above and tap start to begin scanning
which overflows to the right losing the word 'scanning'.
This causes an exception by the rendering library with a yellow warning on screen and the exception reported to console, but does not stop the app running and continuing.

To Reproduce
Steps to reproduce the behavior:

  1. Run the example on an iPhone6, iPhone6s, iPhone7, iPhone8, iPhoneSE with horizontal screen size 750 pixels.

Expected behavior
No text overflow.

Additional context
iOS13, Xcode 11.5

The console report is:

════════ Exception caught by rendering library
The following assertion was thrown during layout:
A RenderFlex overflowed by 76 pixels on the right.

The relevant error-causing widget was
Row
lib/…/ui/device_list.dart:117
The overflowing RenderFlex has an orientation of Axis.horizontal.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex.

Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.

The specific RenderFlex in question is: RenderFlex#3e75a relayoutBoundary=up4 OVERFLOWING

Long Device Name Getting Cutoff

Describe the bug
I'm running into an issue with a long device name getting characters cut-off and I'm wondering if there's any debug steps I can take to work isolate where this is occurring. For example, I have a device who's name is: 11111111-2222-3333-4444-123456789012, it looks like the last couple of characters are getting cut off when the scanning result info returns. This is what I will get back: 11111111-2222-3333-4444-12345

To Reproduce
Steps to reproduce the behavior:

  1. Start scan using FlutterReactiveBle.scanForDevices(withServices: [])
  2. Listen for discovered devices and print to console device name:
listen((device) {
  developer.log('Name=${device.name}');
});
  1. Observe a long name has the last couple characters are cut off.

Expected behavior
Full name of device is returned

  • I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above

Smartphone / tablet

  • Device: Samsung Galaxy Note8

  • OS: Android 8

  • Package version: v2.2.0

  • Device: Google Pixel 2

  • OS: Android 8

  • Package version: v2.2.0

Peripheral device

  • Vendor, model: Raspberry Pi, Raspbian 2020-05-27
  • Does it run a custom firmware / software: no

Additional context
This issue does not affect iOS

Prefer CBAdvertisementDataLocalName over peripheral.name

Describe the bug
We found a bug in an application using flutter_reactive_ble, this bug resulted in a device showing a different device's name. We believe the cause of the problem is described in the StackOverflow link below.

To Reproduce
Steps to reproduce the behavior:
When using peripheral.name to define a devices name, the iOS CoreBluetooth API is not able to change the name of the device. Therefore the CBAdvertisementDataLocalName should be used.
https://stackoverflow.com/questions/25938274/incorrect-ble-peripheral-name-with-ios

Expected behavior

  • I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above
    Yes, previously we used our own flutter_blues fork, this flutter package uses the CBAdvertisementDataLocalName and the bug occured after releasing our application after implementing flutter_reactive_ble

Smartphone / tablet

  • OS: iOS
  • Package version: [e.g. 2.3.0]

Peripheral device

  • Vendor, model: CUSTOM
  • Does it run a custom firmware / software: yes / no

Additional context
Add any other context about the problem here.

No catchable exception when BT is disabled in scanRepeater

Describe the bug
When BT is disabled in Android and the scan is started there is an exception internally but the exception is not handled to the calling program and therefore cannot be handled by the app.

To Reproduce
Steps to reproduce the behavior:

  1. In Android switch off BT
  2. start _scanner.startScan(null); from the example program
  3. Check the console for failures

Expected behavior
We need a stream event for exceptions and some additional information about the type of exception

Additional context

I/flutter (21735): ErrorValue: Exception: GenericFailure<ScanFailure>(code: ScanFailure.unknown, message: "Bluetooth disabled (code 1)")
I/flutter (21735): #0      Result.dematerialize.<anonymous closure> (package:flutter_reactive_ble/src/model/result.dart:22:13)
I/flutter (21735): #1      Result.iif (package:flutter_reactive_ble/src/model/result.dart:34:21)
I/flutter (21735): #2      Result.dematerialize (package:flutter_reactive_ble/src/model/result.dart:15:28)
I/flutter (21735): #3      FlutterReactiveBle.scanForDevices.<anonymous closure>.<anonymous closure> (package:flutter_reactive_ble/src/reactive_ble.dart:274:49)
I/flutter (21735): #4      _MapStream._handleData (dart:async/stream_pipe.dart:229:31)
I/flutter (21735): #5      _ForwardingStreamSubscription._handleData (dart:async/stream_pipe.dart:166:13)
I/flutter (21735): #6      _rootRunUnary (dart:async/zone.dart:1192:38)
I/flutter (21735): #7      _CustomZone.runUnary (dart:async/zone.dart:1085:19)
I/flutter (21735): #8      _CustomZone.runUnaryGuarded (dart:async/zone.dart:987:7)
I/flutter (21735): #9      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
I/flutter (21735): #10     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:266:7)
I/flutter (21735): #11     _ForwardingStreamSubscription._add (dart:async/stream_pi

Subscribing to characteristics crashes on iOS, works fine on Android

First of all, thanks a lot for the library and the nice documentations :)
Unfortunately, I couldn't get it working as expected on iOS.

Describe the bug
After successfully discovering, then connecting to a Bluetooth device (Blood pressure monitoring device), I could not subscribe and read the characteristics of the device.

To Reproduce
Steps to reproduce the behavior:

  1. Connect to one device using connectToDevice()
  2. subscribe to a protected characteristic subscribeToCharacteristic()
  3. Observed a failure with the exception below
flutter: [BLE] subscribeToCharacteristic error is : PlatformException(flutter_reactive_ble.Central.(unknown context at $1071c0d30).Failure:2, The operation couldn’t be completed. (flutter_reactive_ble.Central.(unknown context at $1071c0d30).Failure error 2.), {})

Expected behavior
Reading blood pressure records similar to what happens on Android
(Receiving characteristics from the subscribeToCharacteristic function)

BlueTooth Service

class BluetoothService implements DisposableService {
  static FlutterReactiveBle _ble = FlutterReactiveBle();

  MedicalDataService _medicalDataService = locator<MedicalDataService>();

  BehaviorSubject<ConnectionStateUpdate> connectionStateUpdate =
      BehaviorSubject();
  BehaviorSubject<List<DiscoveredDevice>> discoveredDeviceList =
      BehaviorSubject();
  BehaviorSubject<int> syncedDataCount = BehaviorSubject();

  StreamSubscription<ConnectionStateUpdate> _connectToDeviceSub;

  StreamSubscription<DiscoveredDevice> _scanForDevicesSub;

  StreamSubscription<List<int>> _subscribeToCharacteristicSub;

  Logger logger = Logger('BLE');

  BluetoothService() {
    print('bluetooth service init');
    _ble.statusStream.listen((event) {
      logger.debug('event = ${event}');
    });
  }

  @override
  void dispose() {
    _connectToDeviceSub?.cancel();
    _scanForDevicesSub?.cancel();
    _subscribeToCharacteristicSub?.cancel();
  }

  discoverDevices(BluetoothDevice device) {
    discoveredDeviceList.add([]);
    _scanForDevicesSub = _ble.scanForDevices(
        withServices: [Uuid.parse(device.uuid)]).listen((discoveredDevice) {
      if (discoveredDeviceList.hasValue &&
          !discoveredDeviceList.value.contains(discoveredDevice)) {
        discoveredDeviceList
            .add(discoveredDeviceList.value..add(discoveredDevice));
      }
    }, onError: (e) {
      logger.debug('discoverDevices error is : ${e}');
    });
  }

  connectToDevice(String deviceId, BluetoothDevice device) {
    List<Uuid> characteristicsUUIDs = [Uuid.parse(device.charId)];
    _connectToDeviceSub = _ble
        .connectToDevice(
            id: deviceId,
            servicesWithCharacteristicsToDiscover: {
              Uuid.parse(device.uuid): characteristicsUUIDs
            },
            connectionTimeout: Duration(seconds: 30))
        .listen((connectionState) {
      connectionStateUpdate.add(connectionState);
      logger.debug(
          'Status update at: ${DateTime.now().toIso8601String()} - state is: ${connectionState}');
    }, onError: (e) {
      logger.debug('connectToDevice error is : ${e}');
    });
  }

  readCharacteristic(DiscoveredDevice discoveredDevice, BluetoothDevice device,
      String charId) async {
    Uuid characteristicsUUID = Uuid.parse(charId);
    QualifiedCharacteristic characteristic = QualifiedCharacteristic(
        characteristicId: characteristicsUUID,
        serviceId: Uuid.parse(device.uuid),
        deviceId: discoveredDevice.id);

    final List<int> response =
        await _ble.readCharacteristic(characteristic).catchError((e) {
      logger.debug('readCharacteristic error is : ${e}');
    });
    return response;
  }

  subscribeToCharacteristic(DiscoveredDevice discoveredDevice,
      BluetoothDevice device, String charId) async {
    syncedDataCount.add(0);
    Uuid characteristicsUUID = Uuid.parse(charId);
    QualifiedCharacteristic characteristic = QualifiedCharacteristic(
        characteristicId: characteristicsUUID,
        serviceId: Uuid.parse(device.uuid),
        deviceId: discoveredDevice.id);

    _subscribeToCharacteristicSub = await _ble
        .subscribeToCharacteristic(characteristic)
        .listen((data) async {
      List<MedDataRecord> records = BluetoothDevice.parse(data, device);
      await records.forEach((record) => _medicalDataService.post((record)));
      syncedDataCount.add(++syncedDataCount.value);
    }, onError: (e, s) {
      syncedDataCount.add(-1);
      logger.debug('subscribeToCharacteristic error is : ${e}');
      logger.debug('subscribeToCharacteristic stack is : ${s}');
    });
    _subscribeToCharacteristicSub.resume();
  }

  Future writeCharacteristic(DiscoveredDevice discoveredDevice,
      BluetoothDevice device, String charId, List<int> byteArray) async {
    Uuid characteristicsUUID = Uuid.parse(charId);
    QualifiedCharacteristic characteristic = QualifiedCharacteristic(
        characteristicId: characteristicsUUID,
        serviceId: Uuid.parse(device.uuid),
        deviceId: discoveredDevice.id);

    var response = await _ble.writeCharacteristicWithResponse(characteristic,
        value: byteArray); // Could be wrong
    return response;
  }
}

Smartphone / tablet

  • Device: Iphone 8 (Also tried with XR and iPad 11)
  • OS: iOS 13
  • Package version: [e.g. 1.0.0]

Peripheral device

  • Beurer, BM54, and other Bearer devices.
  • Does it run a custom firmware: no

Additional context

  • Android works fine with the same code
  • Made sure the pairing is successful using vendor's app (Beurer Health Manager)

Flutter Doctor
Running flutter doctor -v result:

[✓] Flutter (Channel stable, v1.17.1, on Mac OS X 10.14.6 18G103, locale en-DE)
    • Flutter version 1.17.1 at /Users/buelenthacioglu/sdk/flutter
    • Framework revision f7a6a7906b (3 weeks ago), 2020-05-12 18:39:00 -0700
    • Engine revision 6bc433c6b6
    • Dart version 2.8.2
 
[!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /Users/buelenthacioglu/Library/Android/sdk
    • Platform android-29, build-tools 29.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.3.1, Build version 11C504
    • CocoaPods version 1.8.4
[!] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
[✓] IntelliJ IDEA Ultimate Edition (version 2019.3.2)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 43.0.3
    • Dart plugin version 193.6015.53
[✓] Connected device (1 available)
    • Karim’s iPhone • 8418dbf9850aaef7c09c6c9760fbc1f02b5a74f8 • ios • iOS 13.3.1

Example app scan doesn't work out of box - android

Describe the bug
Scanning returns no results when it should.

To Reproduce
Steps to reproduce the behavior:

  1. Build example app.
  2. Run on Android (Galaxy Note 8, Android 9).
  3. After starting running it, give location permission (which is a different issue).
  4. Attempt to scan for a common UUID (i.e. 1800, 1801)

Expected behavior
Scan returns devices.

  • [X ] I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above

Smartphone / tablet

  • Device: Galaxy Note 8
  • OS: Android 9
  • Package version: Current master, March 2

Peripheral device

  • Any! nRF Connect finds many devices around me.

Additional context
n/a

Using device.name as a discriminant to select (or ignore) discoverable devices

It would be useful to have the ability to use device.name (or a portion, perhaps the first couple of characters) as a discriminant to select (or ignore) discoverable devices.

I explored your use of _isValidUuidInput in device_list.dart but I could not quite come up with an optimum alternative .

Could please help with an example along the lines of the following, which is obviously incorrect in Dart?

device.name.startsWith('xyz')

Thanks.

Alfredo

Read characteristics on iOS is not working

Describe the bug
When a device connection is established, characteristics cannot be read on iOS, whereas on Android it works without any problem. Following error is printed:

To Reproduce
Steps to reproduce the behavior:

  1. Connect to one device using connectTo()
  2. Subscribe to a non-protected characteristic
  3. Observe a failure with following exception

Error unsubscribing from notifications: PlatformException(flutter_reactive_ble.Central.(unknown context at $103218a20).Failure:1, The operation couldn’t be completed. (flutter_reactive_ble.Central.(unknown context at $103218a20).Failure error 1.), {})

    _connectedDeviceStream.where((device) => device.connectionState == DeviceConnectionState.connected).listen((onData) async {
      var chars = _ble.subscribeToCharacteristic(
        QualifiedCharacteristic(characteristicId: _charUuid, serviceId: _serviceUuid, deviceId: deviceId),
      );
      var listOfChars = await chars.toList();
      print('chars ${listOfChars.runtimeType} $listOfChars');
      _values.add(listOfChars);
    });

Tablet

  • Device: iPad (7th generation)
  • OS: iOS 13.3.1

Ble Undeliverable Exception Documentation

Is your feature request related to a problem? (please describe)
The ReadMe section for Ble Undeliverable Exception should contain a complete working code sample and some more detailed instructions.

Describe the solution you'd like
To catch the Ble Undeliverable exception in Java you can do the following . . .

  1. Add implementation "com.polidea.rxandroidble2:rxandroidble:1.11.1" to the dependencies section of your build.gradle file (source).

  2. Then add the following to MainActivity.java

import io.flutter.embedding.android.FlutterActivity;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import com.polidea.rxandroidble2.exceptions.BleException;
import io.reactivex.exceptions.UndeliverableException;
import io.reactivex.plugins.RxJavaPlugins;

public class MainActivity extends FlutterActivity {
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        RxJavaPlugins.setErrorHandler(throwable -> {
            if (throwable instanceof UndeliverableException && throwable.getCause() instanceof BleException) {
                System.out.println('!' * 80);
                System.out.println("Caught UndeliverableException from flutter_reactive_ble.");
                System.out.println('!' * 80);
                return; // ignore BleExceptions as they were surely delivered at least once
            }
            throw new RuntimeException("Unexpected Throwable in RxJavaPlugins error handler", throwable);
        });
    }
}

Additional context
As for me, my experience with android is limited and so it took me a long time to build a complete working version from the code you had in your README. Also, you can find some helpful examples here in the RxAndroidBle library examples folder.

Connecting with connectionTimeout parameter fails immediately with GATT ERROR 133

Describe the bug
Connecting to a device with a connectionTimeout value given, results most of the times in a GATT ERROR 133 (see the logcat log attached below). Not having a connectionTimeout parameter set results in a successful (and pretty fast) connection.

Seems like an android-only issue, the same code works with iOS just fine.

To Reproduce
Steps to reproduce the behavior:

  1. Connect to one device using .connectToDevice(id: ..., connectionTimeout: Duration(seconds: 10))
  2. See the failed attempt to connect in you log

Expected behavior
The expected behavior would be an established connection or a timeout after the set duration

  • I tried doing the same with a general BLE scanner application

Smartphone / tablet

  • Device: OnePlus 5t
  • OS: Android 9
  • Package version: 2.1.0

Peripheral device

  • Vendor, model: Custom
  • Does it run a custom firmware / software: no

Additional context

E/AccessibilityBridge( 7512): VirtualView node must not be the root node.
D/PluginController( 7512): Start connecting for device 78:DB:2F:D0:BC:D2
D/PluginController( 7512): Start connecting for device 78:DB:2F:D0:BC:D2
D/DeviceConnectionHandler( 7512): Try to connect to device 78:DB:2F:D0:BC:D2
D/DeviceConnectionHandler( 7512): Try to connect to device 78:DB:2F:D0:BC:D2
D/DeviceConnector( 7512): Connecting device 78:DB:2F:D0:BC:D2
D/DeviceConnector( 7512): Connecting device 78:DB:2F:D0:BC:D2
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=0
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=0
D/BluetoothGatt( 7512): connect() - device: 78:DB:2F:D0:BC:D2, auto: false
D/BluetoothGatt( 7512): registerApp()
D/BluetoothGatt( 7512): registerApp() - UUID=d1024742-f90f-4f43-ab6d-1f9fbfe29569
D/BluetoothGatt( 7512): onClientRegistered() - status=0 clientIf=9
I/flutter ( 7512): ### CONNECTING ###
E/AccessibilityBridge( 7512): VirtualView node must not be the root node.
E/AccessibilityBridge( 7512): VirtualView node must not be the root node.
D/BluetoothGatt( 7512): onClientConnectionState() - status=133 clientIf=9 device=78:DB:2F:D0:BC:D2
D/DeviceConnector$establishConnection( 7512): Connection established for device 78:DB:2F:D0:BC:D2
D/DeviceConnector$establishConnection( 7512): Connection established for device 78:DB:2F:D0:BC:D2
D/ReactiveBleClient$connectToDevice( 7512): Connect 78:DB:2F:D0:BC:D2 fails: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 133 (GATT_ERROR)
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=0
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=0
D/ReactiveBleClient$connectToDevice( 7512): Connect 78:DB:2F:D0:BC:D2 fails: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 133 (GATT_ERROR)
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Error conn device:  78:DB:2F:D0:BC:D2 error=Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 133 (GATT_ERROR)
I/chatty  ( 7512): uid=10560(com.camparound.truma.cooler.truma_cooler) identical 2 lines
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Error conn device:  78:DB:2F:D0:BC:D2 error=Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 133 (GATT_ERROR)
D/BluetoothManager( 7512): getConnectionState()
D/BluetoothManager( 7512): getConnectedDevices
I/flutter ( 7512): ### CONNECTING ###
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=2
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=2
D/BluetoothGatt( 7512): close()
D/BluetoothGatt( 7512): unregisterApp() - mClientIf=9
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=3
D/DeviceConnectionHandler$listenToConnectionChanges( 7512): Update device: 78:DB:2F:D0:BC:D2 status=3
D/PluginController( 7512): stop notifications
I/chatty  ( 7512): uid=10560(com.camparound.truma.cooler.truma_cooler) identical 12 lines
D/PluginController( 7512): stop notifications
I/flutter ( 7512): ### CONNECTION FAILED ###: GenericFailure<ConnectionError>(code: ConnectionError.failedToConnect, message: "Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 133 (GATT_ERROR)") ~~ with DeviceConnectionState.disconnected
D/PluginController( 7512): Disconnect device: 78:DB:2F:D0:BC:D2
D/PluginController( 7512): Disconnect device: 78:DB:2F:D0:BC:D2
E/AccessibilityBridge( 7512): VirtualView node must not be the root node.

Allow scanForDevices without service uuid

The README for scanForDevices states that "the withService parameter is required.".

I would like to scan for every BLE devices around. What is the reason to enforce the service filter?

Add permission documentation for iOS & Android

Because we need to add permissions to android & iOS before we can get this to work.

This should be added to the readme as well.

For android, it will be added automatically. But is that also the case for iOS?

example can't connect to iphone from android

Describe the bug
the example app can scan found my iphone, but can't connect to iphone from my android

Expected behavior
should connected to my iphone

  • [ yes ] I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above

Smartphone / tablet

  • Device: iphone xs max, redmi 10x
  • OS: ios 13, MIUI 12.0.4
  • Package version: [e.g. 1.0.0]

Scanning parameters are not set

Describe the bug
When I try to scan for devices it always throws an Exception. The demo application works fine but when I try to use it on my app it doesn't work.

To Reproduce
Initialize and then scan with scanForDevices

Expected behavior
Print Log a list of MAC addresses of the devices.

  • I tried doing the same with a general BLE scanner application (e.g. nRF Connect) and it exhibits the expected behavior as described above

Smartphone / tablet

  • Device: MiPAD4Plus
  • OS: Android 10
  • Package version: 2.3.0 | git master

Error 'Kotlin reflection is not available' when sending writeCharacteristicWithResponse

Describe the bug
Everytime a writeCharacteristicWithResponse is dispatched I see in the log:

D/PluginController$executeWriteAndPropagateResultToChannel( 8898): Value succesfully written, function writeCharacteristicWithResponse (Kotlin reflection is not available)

To Reproduce
Steps to reproduce the behavior:

  1. Dispatch writeCharacteristicWithResponse

Smartphone

  • Device: Samsung A107F
  • OS: Android 10
  • Package version: 2.3.0

Peripheral device

  • Vendor, model: raspberry pi 3 b+
  • Go code implementing go-ble

Additional context
It seems that everything works correctly even though the error float

Error compiling for iOS fatal error: 'flutter_reactive_ble/flutter_reactive_ble-Swift.h' file not found

When compiling v2.0.0 for iOS device, I receive the fatal error: .pub-cache/hosted/pub.dartlang.org/flutter_reactive_ble-2.0.0/ios/Classes/ReactiveBlePlugin.m:2:9: fatal error: 'flutter_reactive_ble/flutter_reactive_ble-Swift.h' file not found
#import <flutter_reactive_ble/flutter_reactive_ble-Swift.h>

I can't find the file in the package. Can you help me?

flutter doctor output:
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, v1.18.0-6.0.pre.115, on Mac OS X 10.15.4 19E287, locale de-DE)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
[✓] Android Studio (version 3.5)
[✓] Connected device (1 available)

• No issues found!

Can't scan with location service disabled

Hi,
I'm unable to scan for devices when the location services are disabled:

D/ScanDevicesHandler$startDeviceScan$$inlined$let$lambda(26938): Error while scanning for devices: Location Services disabled (code 4)

I'm not sure what I'm doing wrong but I think I should be able to scan for devices when only the bluetoothservices are enabled.

I'm getting this on Android 8, with flutter_reactive_blue 1.1.0

I'm just doing something along the line of:

_scanSubscription = bleClient.scanForDevices(
  withService: BTDevice.serviceUuid,
  scanMode: ScanMode.lowLatency,
).listen(
  (device) {
  },
);

I also added all the permissions required in the AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

By the way, using FlutterBlue on the same device doesn't require location services to be on in the phone settins.

Peripheral mode support

Is your feature request related to a problem? (please describe)
It would be great if peripheral mode is supported

Improve our public API

Is your feature request related to a problem? (please describe)
When we developed the library we decided to have a facade FlutterReactiveBle where a user can interact with. Intuitively it feels more natural for operations like write, read, subscribe etc to be operated on a device. This is also closer to the approach of iOS (CBPeripheral) and Android (BluetoothGatt).

Describe the solution you'd like
When we scan for devices we will get a BlePeripheral or BluetoothDevice. On this bluetooth device we are able to execute the following operations:

  • connect and disconnect
  • observeConnectionState
  • read, write and subscribe to a characteristic
  • request MTU size
  • request connection priority

Example pseudo code

final device =  await _ble.scanForDevices(withServices: serviceIds).first;

await device.readCharacteristic(serviceUuid: service, characteristicUuid: charUuid);

await device.requestMtu(mtuSize:250);

Describe alternatives you've considered
Let's use this ticket as a discussion how we can improve our API and to reflect on our current API.

When I Turn off BLE or disconnect a device my app crashes with flutter_reactive_ble v2.4

When I Turn off BLE or disconnect a device my app crashes on Flutter 1.20.1 (but not on 1.17.5)

Hello,

Firstly, thank you for your great job :)

I’ve an issue on flutter 1.20.1 but not on 1.17.5, I don't know if the issue comes from the flutter update or the library ?

My issue : When I turn off the BLE or if I disconnect manually/physically (not via code) a BLE device, my app crashes on flutter 1.20.1 (but not on 1.17.5).

--- EDIT ---

My issue : When I turn off the BLE or if I disconnect manually/physically (not via code) a BLE device, my app crashes with flutter_reactive_ble v2.4 (after subscribing to device characteristics).

It seems the issue comes from the v2.4 of this lib.

Flutter v1.17.5 + flutter_reactive_ble v2.3 = OK
Flutter v1.20.1 + flutter_reactive_ble v2.3 = OK
Flutter v1.17.5 + flutter_reactive_ble v2.4 = CRASH
Flutter v1.20.1 + flutter_reactive_ble v2.4 = CRASH

--- END EDIT ---

I don’t know how to handle this exception, do you have any idea ?

Thank you very much

info :
Device : Samsung Galaxy A10
OS : Android 10

com.polidea.rxandroidble2.exceptions.BleDisconnectedException com.polidea.rxandroidble2.exceptions.BleAdapterDisabledException

io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status -1 (UNKNOWN) E/AndroidRuntime(21736): at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) E/AndroidRuntime(21736): at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) E/AndroidRuntime(21736): at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:281) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255) E/AndroidRuntime(21736): at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124) E/AndroidRuntime(21736): at android.os.Handler.handleCallback(Handler.java:883) E/AndroidRuntime(21736): at android.os.Handler.dispatchMessage(Handler.java:100) E/AndroidRuntime(21736): at android.os.Looper.loop(Looper.java:237) E/AndroidRuntime(21736): at android.app.ActivityThread.main(ActivityThread.java:7948) E/AndroidRuntime(21736): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(21736): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) E/AndroidRuntime(21736): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) E/AndroidRuntime(21736): Caused by: com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status -1 (UNKNOWN) E/AndroidRuntime(21736): at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$3.apply(DisconnectionRouter.java:53) E/AndroidRuntime(21736): at com.polidea.rxandroidble2.internal.connection.DisconnectionRouter$3.apply(DisconnectionRouter.java:50) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:57) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableConcatMap$ConcatMapDelayErrorObserver$DelayErrorInnerObserver.onNext(ObservableConcatMap.java:506) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableRefCount$RefCountObserver.onNext(ObservableRefCount.java:227) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservablePublishAlt$PublishConnection.onNext(ObservablePublishAlt.java:177) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableUnsubscribeOn$UnsubscribeObserver.onNext(ObservableUnsubscribeOn.java:60) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58) E/AndroidRuntime(21736): at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66) E/AndroidRuntime(21736): at com.polidea.rxandroidble2.RxBleAdapterStateObservable$1$1.onReceive(RxBleAdapterStateObservable.java:67) E/AndroidRuntime(21736): at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1646) E/AndroidRuntime(21736): at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2) E/AndroidRuntime(21736): ... 7 more E/AndroidRuntime(21736): Caused by: com.polidea.rxandroidble2.exceptions.BleAdapterDisabledException E/AndroidRuntime(21736): ... 21 more

Support iOS 13 in the example app

As reported in the issue 12, the example app needs some updates to "Info.plist" to properly work on iOS 13.

Specifically check NSBluetoothAlwaysUsageDescription and NSBluetoothPeripheralUsageDescription parameters.

Ability to disconnect from a device

So I was digging in the code looking for a way to programmatically disconnect from a device and found the DisconnectFromDeviceRequestin the generated pb dart file. But it seems like this feature is not made available in the Method channel in any way? I would propose to add this as a feature making it possible to also disconnect from a device in the same way you're able to _ble.connectToDevice(...

Improve architecture example app

Is your feature request related to a problem? (please describe)
The architecture does not reflect a super nice way how to user our library in the app

Describe the solution you'd like
Extract BLE related code into a seperate component (e.g. BLOC)

About value type for the write question

Is your feature request related to a problem? (please describe)

final characteristic = QualifiedCharacteristic(serviceId: serviceUuid, characteristicId: characteristicUuid, deviceId: foundDeviceId);
reactiveBleClient.writeCharacteristicWithoutResponse(characteristic, value: [0x00]);

The parameter must be type of int hex?

Describe the solution you'd like

The result obtained by bit operation

for example:

int result = ( 1 << 7 ) | 100;

result is 228;

The hexadecimal string is obtained by using the method toRadixString(16) , get e4 String

According to the document, the parameter should be 0xe4

But I can't find a way to convert e4 to 0xe4

Describe alternatives you've considered

Maybe hexadecimal strings can be supported?

characteristic for Notification (subscribeToCharacteristic) not working on iOS

I have flutter code (laone) using flutter_reactive_ble v2.4.0 which works for Android 9 but raises an exception for iOS. The code allows the selection of a single device from a list of found devices, then when Connect is clicked for that device, it should connect and send some initial data requests, which are then received using a subscribeToCharacteristic method and processed.
On iOS, the exception seems to be due to the subscribeToCharacteristic failing because no trace of the incoming replies is found.
Since the flutter code works on Android, and I can communicate with the device using the iOS app Blue Chat, which also uses a characteristic subscription, the remote server responses seem valid. In the server log, I can see the initial data requests (10 of them) being received and replied to, so the iOS connection is made and the transmit aspect of flutter_reactive_ble is working on iOS.
I have tried with the rxUuid in both long form and 32 bit short form, as suggested in #76.

The connection code is:

static Uuid myServiceId = Uuid.parse('6e400001-b5a3-f393-e0a9-e50e24dcca9e');
static List<Uuid> myServices = [myServiceId];
static Uuid txUuid = Uuid.parse('6e400002');
static Uuid rxUuid = Uuid.parse('6e400003');

connectDevice(DiscoveredDevice device) {
     _ble.connectToAdvertisingDevice(
          id: device.id,
          withServices: myServices,
          prescanDuration: const Duration(seconds: 1),
          servicesWithCharacteristicsToDiscover: {myServiceId: [txUuid, rxUuid]},
          connectionTimeout: const Duration(seconds:  2),
        ).listen((connectionState) {
          // Handle connection state updates
        }, onError: (dynamic error) {
          // Handle a possible error
        });
    rxCharacteristic = QualifiedCharacteristic(
        serviceId: myServiceId,
        characteristicId: rxUuid,
        deviceId: device.id);
    rxSubscription = _ble.subscribeToCharacteristic(rxCharacteristic).listen((data) {
        onDataReceived(data);
    };
    txCharacteristic = QualifiedCharacteristic(
        serviceId: myServiceId, characteristicId: txUuid, deviceId: device.id);
    sendInitialCommands();
    connectedDevice = device;
  }

For the working Android code, the console shows:

I/flutter (17626): connecting to 
I/flutter (17626): 0
I/flutter (17626): done
I/flutter (17626): disconnected device
I/flutter (17626): connecting to Zoom
I/flutter (17626): ====sendInitialCommands
I/flutter (17626): ====InitialCommands==Sent
D/BluetoothGatt(17626): connect() - device: A4:CF:12:78:10:3E, auto: true
D/BluetoothGatt(17626): registerApp()
D/BluetoothGatt(17626): registerApp() - UUID=1998bf31-c89d-4a37-b12e-f690c8d0334f
D/BluetoothGatt(17626): onClientRegistered() - status=0 clientIf=7
D/BluetoothGatt(17626): onClientConnectionState() - status=0 clientIf=7 device=A4:CF:12:78:10:3E
D/BluetoothGatt(17626): discoverServices() - device: A4:CF:12:78:10:3E
D/BluetoothGatt(17626): onConnectionUpdated() - Device=A4:CF:12:78:10:3E interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt(17626): onSearchComplete() = Device=A4:CF:12:78:10:3E Status=0
D/BluetoothGatt(17626): onConnectionUpdated() - Device=A4:CF:12:78:10:3E interval=30 latency=0 timeout=500 status=0
D/BluetoothGatt(17626): setCharacteristicNotification() - uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e enable: true
I/flutter (17626): Received: [y 10]
I/flutter (17626): Received: [x 8]
I/flutter (17626): Received: [f 2.0.0-lc-e58]
I/flutter (17626): ** ZoomController.onDevicePropertyChange **
I/flutter (17626): Setter for firmwareVersion invoked
I/flutter (17626): ** ZoomController.onDevicePropertyChange **
I/flutter (17626): Received firmware version: 2.0.0-lc-e58
I/flutter (17626): Received: [h 160]

where the I/flutter lines are debug messages and the lower set show the responses being received from the first 3 of the 10 commands, and then processed, with the final line showing the 4th response being received.
The iOS log shows the same first 7 log lines and then the exception. I do not recognise the Uuid it claims is unknown in the final log line.

flutter: connecting to
flutter: 0
flutter: done
flutter: disconnected device
flutter: connecting to Zoom
flutter: ====sendInitialCommands
flutter: ====InitialCommands==Sent
flutter: RX error: PlatformException(flutter_reactive_ble.Central.(unknown context at $100d47ef0).Failure:1, The operation couldn’t be completed. (flutter_reactive_ble.Central.(unknown context at $100d47ef0).Failure error 1.), {})
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: Exception: GenericFailure<WriteCharacteristicFailure>(code: WriteCharacteristicFailure.unknown, message: "A peripheral 0E76782B-8B93-89F0-B597-8F2963FAE171 is unknown (make sure it has been discovered)")
#0      Result.dematerialize.<anonymous closure> (package:flutter_reactive_ble/src/model/result.dart:22:13)
#1      Result.iif (package:flutter_reactive_ble/src/model/result.dart:34:21)
#2      Result.dematerialize (package:flutter_reactive_ble/src/model/result.dart:15:28)
#3      ConnectedDeviceOperation.writeCharacteristicWithResponse.<anonymous closure> (package:flutter_reactive_ble/src/connected_device_operation.dart:34:39)
#4      _rootRunUnary (dart:async/zone.dart:1192:38)
#5      _CustomZone.runUnary (dart:async/zone.dart:1085:19)
#6      _FutureListener.handleValue (dart:async/future_impl.dart:141:18)
#7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:682:45)
#8      Future._propagateToListeners (dart:async/future_impl.dart:711:32)
#9      Future._completeWithValue (dart:async/future_impl.dart:526:5)
#10     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:36:15)
#11     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:298:13)
#12     MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart)
<asynchronous suspension>
#13     MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
#14     PluginController.writeCharacteristicWithResponse (package:flutter_reactive_ble/src/plugin_controller.dart:192:10)
#15     ConnectedDeviceOperation.writeCharacteristicWithResponse (package:flutter_reactive_ble/src/connected_device_operation.dart:33:12)
#16     FlutterReactiveBle.writeCharacteristicWithResponse (package:flutter_reactive_ble/src/reactive_ble.dart:170:37)
<asynchronous suspension>
#17     ZoomController.sendString (package:laone/controllers/ZoomController.dart:520:12)
#18     ZoomController.sendCmdGetSwitchQty (package:laone/controllers/ZoomController.dart:343:11)
#19     ZoomController.sendInitialCommands (package:laone/controllers/ZoomController.dart:476:5)
#20     ZoomController.configureDeviceSettings (package:laone/controllers/ZoomController.dart:468:10)
#21     ZoomController.connectDevice.<anonymous closure> (package:laone/controllers/ZoomController.dart:437:9)
#22     new Future.delayed.<anonymous closure> (dart:async/future.dart:318:39)
#23     _rootRun (dart:async/zone.dart:1180:38)
#24     _CustomZone.run (dart:async/zone.dart:1077:19)
#25     _CustomZone.runGuarded (dart:async/zone.dart:979:7)
#26     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1019:23)
#27     _rootRun (dart:async/zone.dart:1184:13)
#28     _CustomZone.run (dart:async/zone.dart:1077:19)
#29     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1003:23)
#30     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: Exception: GenericFailure<WriteCharacteristicFailure>(code: WriteCharacteristicFailure.unknown, message: "A peripheral 0E76782B-8B93-89F0-B597-8F2963FAE171 is unknown (make sure it has been discovered)")

Reactive ble refactoring

During code review we found out that the following methods are quite big and are candidates of being extracted into a separate component:

  • scanfordevices
  • connectToDevice
  • subSribeToCharacteristics

How do I get a list of all services and characteristics for a device?

How do I get a list of all services and characteristics for a device? I've looked at the documentation but I could not find anything related to this. I see there is a way to read/write to a particular characteristic but no way to get all the services and characteristics.

Would appreciate any pointers.

No way of knowing if peripheral is connectable

Is your feature request related to a problem? (please describe)
Right now it's not possible to check if the found peripheral is connectable. There are devices that advertise without being connectable, so it would be good to filter out those and only allow connectable devices.

Describe the solution you'd like
For iOS, CBAdvertisementDataIsConnectable lets you know wether a peripheral is connectable. It would be great if this gets passed through.
However, since this plugin relies on RxAndroidBle, it is currently not possible to check if a peripheral is connectable on Android. See ticket dariuszseweryn/RxAndroidBle#668

Describe alternatives you've considered
x

Additional context
x

Crash when disconect

Describe the bug
The lib crashed when i shutdown the connected peripheral.

Expected behavior
Crashed Stack

  Process: com.wellpay.deoxys, PID: 29020
    io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | com.polidea.rxandroidble2.exceptions.BleDisconnectedException: Disconnected from MAC='XX:XX:XX:XX:XX:XX' with status 8 (GATT_INSUF_AUTHORIZATION or GATT_CONN_TIMEOUT)
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:313)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.observable.ObservableReplay$ReplayObserver.dispose(ObservableReplay.java:271)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.observable.ObservableRefCount.timeout(ObservableRefCount.java:137)
        at io.reactivex.internal.operators.observable.ObservableRefCount.cancel(ObservableRefCount.java:104)
        at io.reactivex.internal.operators.observable.ObservableRefCount$RefCountObserver.dispose(ObservableRefCount.java:233)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.mixed.CompletableAndThenObservable$AndThenObservableObserver.dispose(CompletableAndThenObservable.java:86)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.dispose(SingleFlatMapObservable.java:84)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.dispose(SingleFlatMapObservable.java:84)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$InnerObserver.dispose(ObservableFlatMap.java:588)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:510)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
        at io.reactivex.internal.operators.observable.ObservableDoOnEach$DoOnEachObserver.dispose(ObservableDoOnEach.java:79)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.disposeAll(ObservableFlatMap.java:504)
        at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.dispose(ObservableFlatMap.java:310)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.dispose(ObservableObserveOn.java:146)
        at io.reactivex.internal.disposables.DisposableHelper.dispose(DisposableHelper.java:124)
        at io.reactivex.internal.observers.LambdaObserver.dispose(LambdaObserver.java:102)
        at com.signify.hue.flutterreactiveble.channelhandlers.CharNotificationHandler.unsubscribeFromNotifications(CharNotificationHandler.kt:46)
        at com.signify.hue.flutterreactiveble.PluginController.stopNotifications(PluginController.kt:231)
        at com.signify.hue.flutterreactiveble.PluginController.access$stopNotifications(PluginController.kt:25)
        at com.signify.hue.flutterreactiveble.PluginController$pluginMethods$11.invoke(PluginController.kt:37)
        at com.signify.hue.flutterreactiveble.PluginController$pluginMethods$11.invoke(PluginController.kt:25)
        at com.signify.hue.flutterreactiveble.PluginController.execute$flutter_reactive_ble_debug(PluginController.kt:75)
        at com.signify.hue.flutterreactiveble.ReactiveBlePlugin.onMethodCall(ReactiveBlePlugin.kt:43)
        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:226)

Smartphone / tablet

  • Device: Pixel4
  • OS: Android 11
  • Package version: 2.2

Improve doc comments for public api

We are still missing:

  Repeater: repeater.dart:5:1
  SerialDisposable: serial_disposable.dart:3:1
  isDisposed: serial_disposable.dart:22:3
  set: serial_disposable.dart:6:3
  dispose: serial_disposable.dart:15:3
  StreamSubscriptionSerialDisposable: serial_disposable.dart:38:1
  WriteCharacteristicInfo: write_characteristic_info.dart:6:1
  WriteCharacteristicFailure: write_characteristic_info.dart:17:1
  Uuid: uuid.dart:6:1
 convertScanModeToArgs: scan_mode.dart:17:1

How to connect multiple different devices at the same time?

Is your feature request related to a problem? (please describe)
Connect multiple devices and write different information to different devices at the same time

Describe the solution you'd like
There is no information about multiple device connection writes in the documentation and examples

Describe alternatives you've considered
Nothing

Additional context
Nothing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.