GithubHelp home page GithubHelp logo

pauldemarco / flutter_blue Goto Github PK

View Code? Open in Web Editor NEW
2.4K 2.4K 1.2K 16.99 MB

Bluetooth plugin for Flutter

License: BSD 3-Clause "New" or "Revised" License

Java 20.65% Ruby 2.97% Objective-C 12.71% Dart 63.37% Swift 0.30%

flutter_blue's People

Contributors

123lxw123 avatar alxkzmn avatar berdroid avatar blaugold avatar brianegan avatar bsheen avatar dustin-graham avatar efortuna avatar ened avatar ezamagni avatar hanabi1224 avatar kschulz-samsung avatar lidongze91 avatar mehmetf avatar mit-mit avatar nicolasdupere avatar pauldemarco avatar rickcasson avatar spekary avatar x0054 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  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

flutter_blue's Issues

Flutter blue Guid 'operator==' will give false positives.

operator == on Guid is just comparing Guid hash codes, and not subsequently comparing Guid values, so will give false positives if the hash codes for two different values collide.

operator ==(other) =>
other is Guid && this.hashCode == other.hashCode;

[iOS]Cannot run in iOS app after adding flutter_blue

I have added flutter_blue to my yaml file after that I'm getting pod error

dependencies:
  flutter:
    sdk: flutter
  flutter_blue: "0.3.1"
  cupertino_icons: ^0.1.0

If I remove flutter_blue then it starts to work normally
Why is this issue happening and how can I solve this?

Bluetooth on Android needs ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission

I tried the example from https://pub.dartlang.org/packages/flutter_blue#-example-tab-
with the install instruction from https://pub.dartlang.org/packages/flutter_blue#-installing-tab-

Running it resulted in a working app, the moment I hit the search button, this message was displayed:

==========================

D/BluetoothAdapter(24334): STATE_ON
D/BluetoothLeScanner(24334): onClientRegistered() - status=0 clientIf=6 mClientIf=0
W/Binder (24334): Binder call failed.
W/Binder (24334): java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
W/Binder (24334): at android.os.Parcel.readException(Parcel.java:1684)
W/Binder (24334): at android.os.Parcel.readException(Parcel.java:1637)
W/Binder (24334): at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:678)
W/Binder (24334): at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:367)
W/Binder (24334): at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
W/Binder (24334): at android.os.Binder.execTransact(Binder.java:565)
D/BluetoothAdapter(24334): STATE_ON

==========================

I tried to add the permissions in AndroidManifest.xml in the android/app/src as they were in the example provided with the package code, but no dice

================

package="com.yourcompany.johanblue">

<!-- The INTERNET permission is required for development. Specifically,
     flutter needs it to communicate with the running application
     to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

================

What are the appropriate steps to get this thing running?
(testing on Moto Z Play, Android 7.1.1 securitypatches december 2017)

Kind Regards,
Johan

NullPointerException when cancelling scanSubscription on android

In android, I got the following error while trying to stop scanning from my application:

E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): Failed to handle method call
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeScanner.stopScan(android.bluetooth.le.ScanCallback)' on a null object reference
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at com.pauldemarco.flutterblue.FlutterBluePlugin.stopScan21(FlutterBluePlugin.java:609)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at com.pauldemarco.flutterblue.FlutterBluePlugin.stopScan(FlutterBluePlugin.java:565)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at com.pauldemarco.flutterblue.FlutterBluePlugin.onMethodCall(FlutterBluePlugin.java:153)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:191)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:133)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at android.os.MessageQueue.next(MessageQueue.java:323)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at android.os.Looper.loop(Looper.java:136)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at android.app.ActivityThread.main(ActivityThread.java:6186)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
E/MethodChannel#plugins.pauldemarco.com/flutter_blue/methods(10734): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
D/BluetoothAdapter(10734): onBluetoothServiceDown: Sending callbacks to 1 clients
D/BluetoothAdapter(10734): onBluetoothServiceDown: Finished sending callbacks to registered clients

The problem here seems to be in stopScan21, that doesn't check whether mBluetoothAdapter.getBluetoothLeScanner() returns null. There seems to be the same problem in startScan21

Improve Documentation

Look at flutter widgets to see how to properly document classes. Right now they are an absolute mess.

Combine state and onStateChanged()

With issue #21 implemented, consider making state a Stream<BluetoothDeviceState> and simply leverage the power of Dart streams, i.e. state.first (if state is only needed once)

Support concurrent characteristic reads via Future.wait

This code should allow concurrent reading of characteristics:

  Future.wait([
    device.readCharacteristic(char1),
    device.readCharacteristic(char2),
// etc.
  ])
  .then((returnsList) {
    print('In Future.wait.then, ${returnsList.length}');
  })
  .catchError((e) {
    print('error $e');
  });

But in fact it never gets to .then ... nor does it throw an error.

Based on the debug messages coming out of flutter_blue it appears that both characteristics are indeed being read. So maybe there's a tweak needed to handle the case that multiple futures are active at the same time?

Covered here in Dart docs: Async

Rename startScan to scan

Now that scanning stops once the subscription to startScan is canceled, we can consider renaming startScan to simply scan.
Original suggestion by @brianegan in PR #17 .

I will be considering this breaking change for a bit, but I'm leaning towards implementing. If you have some thoughts please share.

[Android] Scan Options

Nested services (secondary services) refactor needed.

As of right now, characteristics and descriptor hold onto their parent service, but do not account for the fact that the service might be a nested service.

Need to think about how to handle this, it doesn't seem iOS supports it.

Difficult to use flutter hot reload with flutter blue

Flutter blue has a map of connections by deviceId kept in a java hashmap that survives across hot reloads, and connect is not allowed to reuse an existing connection. Thus it is not possible to connect to the same device after a hot reload.

To reproduce:

  1. Run app, connect to a device.

  2. Hot reload app.

  3. Try to connect to same device, run into this:

    case "connect":
    ...
    // If device is already connected, return error
    if(mGattServers.containsKey(deviceId) && isConnected) {
    result.error("already_connected", "connection with device already exists", null);
    return;
    }

Device disconnection is a private method ('_cancelConnection') so I can't kill the connection myself as a workaround.

So, for now, I am just doing a full app restart each time.

  • Regards

David

Package protobuf has no versions that match >=0.5.5 <0.6.0 derived from:

When trying to add flutter_blue to the most basic app setup with no other dependencies in android studio 3.0 it gives this error message:

/home/maarten/flutter/bin/flutter --no-color packages get
Running "flutter packages get" in tanngrisnir...
Package protobuf has no versions that match >=0.5.5 <0.6.0 derived from:

  • flutter_blue 0.2.4 depends on version ^0.5.5
    pub get failed (1)
    Process finished with exit code 1

this is my pubspec.yaml:

name: tanngrisnir
description: Remote control app for tanngrisnir

depend
dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://wwname: tanngrisnir
description: Remote control app for tanngrisnir

depend
dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: trueencies:
  flutter_blue: "^0.2.4"
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true


AdvertisementData contains empty values on iOS

Hi,

On iOS, I'm not seeing any data for the following properties on AdvertisementData in my ScanResult event stream handler:

  • localName
  • manufacturerData
  • serviceData

I observed this to be consistent over ScanResults for responses for 19 different devices.

localName returns an empty String, and manufacturerData and serviceData return an empty List<int>.

Let me know if I can provide more details or if I can help in troubleshooting, debugging, or verifying a fix.

Thanks.

Consider creating a Platform Channel manager

As of right now, whenever an object is created, it creates it's own PlatformChannel with it's specific path name. If however another object is created for that same GUID path, we will have duplicate PlatformChannels for the same path, and neither will work.

Consider creating a PlatformChannel Factory, which will keep a HashMap of path to channels list, and can be used by any objects requiring a channel.

bluetoothDevice.discoverServices() doesn't return anything

I'm having trouble getting the list of services from a bt device, my snippet:

List<BluetoothService> services = await widget.device.discoverServices();
print("success discovered");

never gets to print "success", here's what i see in the log:

D/FlutterBluePlugin(24804): onServicesDiscovered: 4 sink:null

It seems the servicesDiscoveredHandler.onListen function (which registers the servicesDiscoveredSink) is called only after onServicesDiscovered; but i can't find out why.

Maybe some change in the flutter framework? I've tried using alpha channel (2017-12-12) and git from yesterday. This seems to happen with flutter_blue 0.2.3 and git HEAD.

If you can't find time to fix this, any hints would be appreciated to maybe enable me to produce a PR.

API for Serial communication

Hi,

I would like to ask is there any way that I can use this plugin for serial communication with another bluetooth device? Is there anywhere that I can look into to implement this function?

Thanks.

Support for advertising

It would be nice to support advertising as well as it is available on ios and Android( >=5.0)

iOS support

An Objective-C implementation is still needed on iOS side.

[iOS] setNotifyValue doesn't reflect changes immediately

This is because the contained CCC descriptor's value has not updated yet in the characteristic sent back in result(...).
Solution:
Move the setNotifyValue callback to a channel method and call from didUpdateNotificationStateForCharacteristic
This would require a new Protobuf type of ProtosSetNotificationResponse

Only one characteristic can notify at a time

Unless I am mistaken, the following code only allows one notification to be active at a time:

/// Notifies when the characteristic's value has changed.
  /// setNotification() should be run first to enable them on the peripheral
  Stream<List<int>> onValueChanged(BluetoothCharacteristic characteristic) {
    return FlutterBlue.instance._characteristicNotifiedChannel
        .receiveBroadcastStream()
        .map((buffer) => new protos.OnNotificationResponse.fromBuffer(buffer))
        .where((p) => p.remoteId == id.toString())
        .map((p) => new BluetoothCharacteristic.fromProto(p.characteristic))
        .where((c) => c.uuid == characteristic.uuid)
        .map((c) {
          characteristic.updateDescriptors(c.descriptors);
          characteristic.value = c.value;
          return c.value;
        });
  }

For many BLE devices it is necessary to listen to notifications from multiple characteristics at the same time. Not to mention from multiple devices!

Dart 2 invokeMethod compatibility

With the upcoming Dart 2 changes we will run into errors when returning anything other than Future<dynamic> from invokeMethod calls.

Calls like:

Future<bool> get isOn => _channel.invokeMethod('isOn');

Need to be updated to:

Future<bool> get isOn async {
 final bool isOn = await _channel.invokeMethod('isOn');
 return isOn;
}

More details in this issue: flutter/flutter#15654

RssiPainterCircle animation is not fluent

  1. Switch AnimatedRssi to use the RssiPainterCircle painter.

  2. Scan for devices

  3. Notice the elastic animation is not picking up where it left off, causing a stuttery look.

NPE thrown from Android Runtime after initiating scan in the example

Attempting to run the example code on a Nexus 7 (running android 6.0.1)

I'm consistently getting this stacktrace and an application crash a few seconds after initiating a scan:

E/AndroidRuntime( 7688): FATAL EXCEPTION: main
E/AndroidRuntime( 7688): Process: com.pauldemarco.flutterblueexample, PID: 7688
E/AndroidRuntime( 7688): java.lang.NullPointerException
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.Protos$BluetoothDevice.setName(Protos.java:2850)
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.Protos$BluetoothDevice.access$4900(Protos.java:2689)
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.Protos$BluetoothDevice$Builder.setName(Protos.java:3089)
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.ProtoMaker.from(ProtoMaker.java:38)
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.ProtoMaker.from(ProtoMaker.java:28)
E/AndroidRuntime( 7688): 	at com.pauldemarco.flutterblue.FlutterBluePlugin$2.onScanResult(FlutterBluePlugin.java:579)
E/AndroidRuntime( 7688): 	at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:355)
E/AndroidRuntime( 7688): 	at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime( 7688): 	at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime( 7688): 	at android.os.Looper.loop(Looper.java:148)
E/AndroidRuntime( 7688): 	at android.app.ActivityThread.main(ActivityThread.java:5417)
E/AndroidRuntime( 7688): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 7688): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
E/AndroidRuntime( 7688): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

onStateChanged should emit state when listened to

Having to do a lot of this:

    // Immediately get the state of FlutterBlue
    _flutterBlue.state.then((s) {
      setState(() {
        state = s;
      });
    });
    // Subscribe to state changes
    _stateSubscription = _flutterBlue.onStateChanged().listen((s) {
      setState(() {
        state = s;
      });
    });

By having onStateChanged() always return current state when listened to, we can avoid the extra then call.

Add tests

Look to other flutter plugins for how to maximize code coverage.

[iOS] discoverServices is not discovering all characteristics and descriptors

Unlike Android, iOS requires all characteristics and descriptors to be explicitly discovered using:
discoverCharacteristics:forService:
discoverDescriptorsForCharacteristic:

Current implementation of Flutter Blue will return the discoverServices call once the first descriptor is received, often being too early and missing other characteristic and services information.

Solution idea: Implement stacks to keep track of services/characteristics/descriptors that still need discovered, and return the discovered tree only when these arrays are empty.

Secondary services channel issue

A secondary service will also receive the channel path of "flutterblue.pauldemarco.com/device/${deviceId.toString()}/service/${serviceId.toString()}/methods"

This could cause conflicts if a primary service shares the same UUID, is this possible in the BLE spec?

Consolidate event channels

There are separate event channels for reading characteristics, reading descriptors, discovering services, etc. Should these be consolidated onto the main method channel, and then dispatched dart side (see firebase_database plugin's Query class)?

(iOS) Peripheral delegate does not seem to unset

Steps to reproduce:

  1. Connect to a device
  2. Notice log messages
  3. Disconnect from device
  4. Reconnect to same device
  5. Notice log messages now x2

Note: This doesn't happen if a difference device is connected to

(iOS) Flutter run sometimes errors

This error is sometimes experienced when trying to flutter run:

[!] ERROR: Parsing unable to continue due to parsing error:
    contained in the file located at /Users/pauldemarco/flutter_blue/example/ios/Podfile.lock
    PODS:
      - !ProtoCompiler (3.4.0):
        - Protobuf (~> 3.0)
      - Flutter (1.0.0)
      - flutter_blue (0.0.1):
        - !ProtoCompiler
        - Flutter
        - flutter_blue/Protos (= 0.0.1)
      - flutter_blue/Protos (0.0.1):
        - !ProtoCompiler
        - Flutter
        - Protobuf
      - Protobuf (3.5.0)
    
    DEPENDENCIES:
      - Flutter (from `/Users/pauldemarco/flutter/bin/cache/artifacts/engine/ios`)
      - flutter_blue (from `/Users/pauldemarco/flutter_blue/ios`)
    
    EXTERNAL SOURCES:
      Flutter:
        :path: /Users/pauldemarco/flutter/bin/cache/artifacts/engine/ios
      flutter_blue:
        :path: /Users/pauldemarco/flutter_blue/ios
    
    SPEC CHECKSUMS:
      !ProtoCompiler: 07d0c441bc00e7f01e84debf7c53794683fbca7c
      Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
      flutter_blue: 6a29a637fac55c8918a01e9d2c3d381612b1357a
      Protobuf: 8a9838fba8dae3389230e1b7f8c104aa32389c03
    
    PODFILE CHECKSUM: 351e02e34b831289961ec3558a535cbd2c4965d2
    
    COCOAPODS: 1.3.1
    
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-core-1.2.1/lib/cocoapods-core/yaml_helper.rb:62:in `rescue in load_string'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-core-1.2.1/lib/cocoapods-core/yaml_helper.rb:57:in `load_string'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-core-1.2.1/lib/cocoapods-core/yaml_helper.rb:75:in `load_file'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-core-1.2.1/lib/cocoapods-core/lockfile.rb:40:in `from_file'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.2.1/lib/cocoapods/config.rb:199:in `lockfile'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.2.1/lib/cocoapods/command.rb:138:in `installer_for_config'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.2.1/lib/cocoapods/command/install.rb:38:in `run'
    /Library/Ruby/Gems/2.3.0/gems/claide-1.0.2/lib/claide/command.rb:334:in `run'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.2.1/lib/cocoapods/command.rb:52:in `run'
    /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.2.1/bin/pod:55:in `<top (required)>'
    /usr/local/bin/pod:22:in `load'
    /usr/local/bin/pod:22:in `<main>'
Error running pod install

Dart imports must be included twice

Flutter plugin imports must also be included in the example's pubspec.yaml. For instance:
convert: "^2.0.1"

I would prefer it to only be needed once, in the libraries pubspec.yaml

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.