Skip to main content

flutter_splendid_ble 1.7.0 copy "flutter_splendid_ble: ^1.7.0" to clipboard
flutter_splendid_ble: ^1.7.0 copied to clipboard

A comprehensive Flutter plugin for interacting with Bluetooth Low Energy (BLE) devices.

Changelog #

All notable changes to the flutter_splendid_ble plugin will be documented in this file.

1.7.0 - 2026-11-02 #

  • Fixed BLE operations silently stopping each other's event streams
    • All central callbacks share one native method channel. Previously, every startScan, connect, observeConnectionState, discoverServices, observeBondState, readCharacteristic, emitCurrentBluetoothStatus, and emitCurrentPermissionStatus call replaced a single shared callback handler, so the stream returned by the previous call stopped receiving events without an error or done event
    • Native callbacks are now delivered to every stream that matches them, the same way characteristic notifications already were. For example, an adapter status stream keeps reporting after a scan starts, a connection stream for one device keeps reporting after connecting to another device, and a running scan keeps delivering results during a concurrent connect or service discovery
    • readCharacteristic now completes only with the read response matching its characteristic's device address and UUID (ignoring case), so concurrent reads no longer interfere with each other. Its listener is released when the read succeeds, fails, or times out
    • Malformed service discovery payloads are now emitted as stream errors instead of being thrown inside the method channel handler
  • Fixed Android scanning and connections failing for the life of the app process when Bluetooth was off as the plugin started
    • The plugin previously cached the BluetoothLeScanner when attaching to the Flutter engine. Android provides no scanner while Bluetooth is off, so plugin startup failed partway, and every later scan, connection, and permission request failed until the process was killed, even after Bluetooth was turned on
    • The scanner is now looked up each time a scan starts or stops, and the plugin only begins answering calls from Dart once it has finished initializing
    • startScan now throws a BluetoothScanException when the scan cannot be started, for example on Android while Bluetooth is turned off. Previously, this surfaced as a raw PlatformException from an unhandled native exception
  • Fixed iOS and macOS not reporting Bluetooth adapter and permission changes to existing status streams
    • iOS previously sent only permission status when CoreBluetooth's state changed, so streams from emitCurrentBluetoothStatus never learned that Bluetooth had been turned on or off after they were created. macOS had the opposite gap and never pushed permission changes
    • Both platforms now push adapter status and permission status whenever CoreBluetooth reports a state change, matching Android. On iOS this also corrects an early "disabled" status reported before CoreBluetooth finishes initializing
  • Scan results now update when a device's advertised content changes
    • Previously, each device was emitted once per scan session, and every later advertisement from it was dropped on all platforms. A device first seen with incomplete data (for example, before its scan response arrived) stayed incomplete for the whole scan, and changes to its advertised data were never reported
    • A device is now emitted again whenever its name, manufacturer data, or advertised service UUIDs change during the scan, so scan streams can contain the same address more than once. Use the latest emission for an address as its current state
    • Changes in RSSI alone are not emitted
    • A result that omits a field, such as an advertisement received without its scan response, keeps the value last emitted for that field, so partial packets do not replace complete data
    • Corrected the ScanSettings.allowDuplicates documentation, which described the setting backwards. On iOS and macOS, true makes CoreBluetooth deliver every advertisement, so content changes are noticed promptly; when unset or false, CoreBluetooth coalesces repeat advertisements and later changes may be noticed late or not at all. The setting has no effect on Android, which always delivers repeat advertisements

Known Limitations #

  • Some native failures are reported with an untargeted error callback that identifies neither a device nor an operation. These errors are delivered only to the stream of the most recently started scan, connection, connection observation, service discovery, or bond observation, as before. Adapter status, permission status, and characteristic read calls no longer take over delivery of these errors

1.6.0 - 2026-10-25 #

  • Cross-platform bonding (pairing) diagnostics
    • Added SplendidBleCentral.observeBondState, returning a Future<Stream<BleBondEvent>> that reports the operating-system-managed bonding process for a peripheral
    • Bonding is performed by the OS, not by the plugin; observeBondState does not initiate a bond, it surfaces the bond-state transitions the OS exposes so apps can show pairing progress and diagnose pairing failures
    • BleBondEvent pairs a BleBondState (none, bonding, bonded, failed, unknown) with optional failure detail
    • A failed bond attempt carries a BleBondFailure describing why it failed
      • category is a normalized, platform-agnostic BleBondFailureCategory (authenticationFailure, authenticationRejected, authenticationTimeout, remoteDeviceDown, removed, unknown) intended for writing recovery logic once across platforms
      • platform, rawCode, domain, and description preserve the raw platform-specific detail for logging and diagnosis
    • Android subscribes to the ACTION_BOND_STATE_CHANGED broadcast, emits the current bond state immediately on subscription, and normalizes the unbond reason code into the shared category set on failure

Known Limitations #

  • iOS and macOS bonding visibility is best-effort and far coarser than Android's, because CoreBluetooth exposes no bonding API, bond-state callback, or bonding failure reason to apps. This is a platform restriction imposed by the operating system, not a limitation of this plugin. On these platforms observeBondState derives updates from the lifecycle of operations on encrypted characteristics: it emits an initial unknown (the real bond state cannot be read), bonding when an acknowledged write to an observed device begins, bonded when it succeeds, and failed with whatever CBATTError/CBError detail is available when it fails with an authentication/encryption error. In practice the iOS/macOS failure category resolves to authenticationFailure or unknown.

1.5.0 - 2026-10-24 #

  • Characteristic notification streams now isolate updates by device address and characteristic UUID, ignoring case.
  • Notification streams retain their shared native receiver when another subscription or BLE operation installs or clears a callback handler. Cancelling one stream listener does not interrupt other characteristic listeners.
  • Rich, cross-platform connection error reporting
    • Connection streams now emit BleConnectionEvent objects that pair the connection state with optional failure detail, rather than a bare BleConnectionState
    • Connection failures and unexpected disconnections now carry a BleConnectionFailure describing why the attempt failed or the link was lost
      • category is a normalized, platform-agnostic BleConnectionFailureCategory (timeout, peerTerminated, hostTerminated, authenticationFailure, connectionLimitReached, unreachable, unknown) intended for writing recovery logic once across all platforms
      • platform, rawCode, domain, and description preserve the raw platform-specific detail for logging and diagnosis
    • iOS and macOS now forward the NSError from didFailToConnect and didDisconnectPeripheral (code, domain, and localizedDescription), normalizing CBError and CBATTError codes into the shared category set
    • Android now forwards the GATT/HCI status code from onConnectionStateChange, normalizing common status codes (such as 8, 19, 22) into the shared category set, and distinguishes a failed connection attempt from an unexpected disconnection of an established link
    • Added a new BleConnectionState.failed value, distinct from disconnected, representing a connection attempt that never succeeded
  • Bug fixes to connection state parsing
    • Fixed a crash where a "FAILED" connection status emitted by iOS and macOS had no corresponding BleConnectionState value, causing the Dart method channel handler to throw a StateError
    • Connection state parsing is now tolerant of unrecognized values, resolving them to BleConnectionState.unknown instead of throwing; this also fixes a case-sensitivity mismatch in getCurrentConnectionState

Breaking Changes #

  • SplendidBleCentral.connect and SplendidBleCentral.observeConnectionState now return Future<Stream<BleConnectionEvent>> instead of Future<Stream<BleConnectionState>>. Listeners that previously received a BleConnectionState now receive a BleConnectionEvent; read the connection state from event.state and the failure detail (when present) from event.failure. Apps that do not need the richer error detail can remain on 1.5.x.
  • The native method channel payload for connection updates changed from a bare status string to a map. This affects only code that bypasses the plugin's Dart API to listen on the bleConnectionState_<address> method channel directly.

1.4.0 - 2026-09-01 #

  • Made macOS characteristic writes with response truly asynchronous
    • writeCharacteristic with write type .withResponse now defers the Dart Future until CoreBluetooth's didWriteValueFor callback confirms the ATT write response
    • This ensures await correctly waits for encrypted characteristic writes, where CoreBluetooth initiates pairing first and retries the write only after the bond is established
    • Writes without response continue to resolve immediately, since no acknowledgement is sent
    • Pending writes are now failed cleanly if the device disconnects mid-operation, preventing the Dart Future from hanging indefinitely
  • Migrated to Android Gradle Plugin 9+
    • Updated AGP to 9.0.1 and Kotlin to 2.3.20 in the example and test apps
    • Updated the Gradle wrapper to 9.1.0
    • Simplified and modernized the plugin's android/build.gradle configuration
  • Documentation formatting cleanup

1.3.3 - 2026-07-28 #

  • Removed maxSdkVersion="30" restriction from location permissions in the Android manifest
    • ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION are no longer capped at API 30
    • Fixes BLE scanning issues on devices where the system requires location permissions regardless of Android version

1.3.2 - 2026-07-25 #

  • Automatic GATT cache refresh on Android for bonded devices during reconnection
    • When reconnecting to a previously bonded device, the plugin now calls BluetoothGatt.refresh() to clear the local attribute cache before proceeding with MTU negotiation
    • This prevents stale cached service/characteristic handles from causing connection failures when a peripheral's GATT table has changed between sessions
    • A 300ms delay is applied after the cache refresh to allow the Bluetooth stack to complete the internal invalidation before issuing GATT operations
    • Non-bonded connections are unaffected and proceed immediately without delay

1.3.1 - 2026-07-25 #

  • Added a comment on the Android side documenting how to clear the GATT cache

1.3.0 - 2026-07-23 #

  • Added Swift Package Manager support for iOS and macOS platforms
    • Created Package.swift manifests for both iOS (targeting iOS 13.0) and macOS (targeting macOS 10.15)
    • Migrated Swift source files to SPM-compatible directory structure (flutter_splendid_ble/Sources/flutter_splendid_ble/)
    • Updated CocoaPods podspec files to reference the new source paths
    • Plugin now supports both Swift Package Manager and CocoaPods for backward compatibility

1.2.0 - 2026-06-25 #

  • Improved Android BLE connection reliability to reduce GATT_ERROR (status 133) failures
    • connect() now closes any existing GATT client for the same device before opening a new one, preventing native GATT slot leaks during rapid reconnect cycles
    • connect() handles null return from connectGatt(), which can occur on some OEMs when the BLE stack is exhausted
    • onConnectionStateChange now verifies GATT instance identity, preventing stale callbacks from a previous connection attempt from interfering with a new connection
  • disconnect() is now a true asynchronous operation on Android
    • The Dart Future returned by disconnect() no longer resolves until the full disconnect lifecycle completes (physical disconnection handshake, GATT close, and native resource release)
    • A 1.5-second fallback timer ensures the Future always resolves even if the BLE stack becomes unresponsive
    • This allows Flutter code to safely await disconnect() before starting a new connection
  • Unified manufacturer data format across Android and iOS

Breaking Changes #

  • Android manufacturer data now includes the vendor ID bytes as a prefix, matching the existing iOS behavior. Previously, Android omitted the vendor ID from the complete manufacturer data payload. Code that parses manufacturer data by byte index may need to be updated to account for the two additional leading bytes.

1.1.0 - 2026-06-05 #

  • Added support for requesting preferred PHY (physical layer) for BLE connections
    • New requestPreferredPhy method supports LE 1M, LE 2M, and LE Coded PHYs
    • Implemented on Android (API 26+); no-op on iOS and macOS where the OS manages PHY selection
  • Added support for requesting connection priority (connection interval)
    • New requestConnectionPriority method with balanced, high, and lowPower options
    • Useful for maximising throughput before large data transfers like OTA firmware updates
    • Implemented on Android; no-op on iOS and macOS
  • Added ability to read active BLE connection parameters
    • New readConnectionParameters method returns TX/RX PHY, connection interval, slave latency, and supervision timeout
    • Available on Android API 26+; returns null on iOS and macOS
  • Added new models: BlePhy, BleConnectionPriority, and BleConnectionParameters
  • Improved scan response handling on Android
    • Enhanced BleScannerHandler to better handle devices that split advertisement data across multiple packets
    • Added legacyMode option to ScanSettings for controlling extended advertising PDU support on Android 8+
  • Improved scan response handling on iOS and macOS
    • Added fallback timeout mechanism for connectable devices whose scan response may not arrive
    • Buffered advertisements are now flushed when a scan session ends or restarts, ensuring no devices are silently dropped
  • Updated advertisement data handling on iOS and macOS for more reliable manufacturer data reporting
  • Updated write operations to support duration measurement
  • Added completeData getter to ManufacturerData for accessing full manufacturer data including ID and payload
  • Updated Android compileSdk to 35 and Kotlin to 2.1.0
  • Updated Android Gradle plugin to 8.7.3
  • Updated fake/mock method channel with implementations for new PHY and connection priority methods
  • Added notification characteristic to ESP32 test firmware
  • Added dynamic security characteristic to ESP32 test firmware
  • Added ability to copy test results in the test app
  • Code cleanup and formatting improvements

0.1.0 - 2023-10-07 #

  • Initial support for Bluetooth operations on Android:
    • Bluetooth status checking.
    • Emitting current Bluetooth status.
    • Bluetooth device scanning.
    • Bluetooth device connection handling.
    • Bluetooth service and characteristic discovery and subscription.
    • Reading from Bluetooth characteristics.
    • Writing to Bluetooth characteristics.
    • Terminating a connection to a BLE device.
  • Android example application to demonstrate basic usage.
  • Comprehensive documentation for Android functionality.

0.2.0 - 2023-11-02 #

  • Finalized support for Android.
  • Added support for Bluetooth operations MacOS:
    • Bluetooth status checking.
    • Emitting current Bluetooth status.
    • Bluetooth device scanning.
    • Bluetooth device connection handling.
    • Bluetooth service and characteristic discovery and subscription.
    • Reading from Bluetooth characteristics.
    • Writing to Bluetooth characteristics.
    • Terminating a connection to a BLE device.
  • Added MacOS support to the example application.
  • Comprehensive documentation for MacOS functionality.
  • Added automated test for all plugin methods.

0.3.0 - 2023-11-07 #

  • Added support for Bluetooth operations on iOS:
    • Bluetooth status checking.
    • Emitting current Bluetooth status.
    • Bluetooth device scanning.
    • Bluetooth device connection handling.
    • Bluetooth service and characteristic discovery and subscription.
    • Reading from Bluetooth characteristics.
    • Writing to Bluetooth characteristics.
    • Terminating a connection to a BLE device.
  • Added iOS support to the example application.
  • Comprehensive documentation for iOS functionality.
  • Added extensive usage/tutorials content to README.

0.4.0 - 2023-11-08 #

  • Fixed linter issues
  • Updated documentation, especially around handling of streams

0.4.1 - 2023-11-08 #

  • Cosmetic updates to README

0.4.2 - 2023-11-08 #

  • README updates

0.5.0 - 2023-11-17 #

  • Updated example app
  • Wrote extensive tutorial article

0.6.0 - 2023-12-16 #

  • Updated dependencies
  • Updated scan filtering by UUID

0.7.0 - 2023-01-11 #

  • Updated dependencies
  • Updated documentation
  • Updated formatting to meet Dart standards

0.8.0 - 2023-01-15 #

  • Clear scan results when restarting BLE scan
  • Updated documentation for example app

0.9.0 - 2024-05-23 #

  • Updated Bluetooth permissions handling process
  • Updated documentation

0.10.0 - 2024-05-24 #

  • Re-formatted project according to Dart standards

0.11.0 - 2024-05-31 #

  • Added ability to filter scans by service UUIDs on macOS
  • Added content to the README about configuring and requesting permissions

0.11.1 - 2024-06-02 #

  • Updated Dartdoc references

0.11.2 - 2024-06-11 #

  • Updated documentation

0.11.3 - 2024-06-14 #

  • Updated documentation

0.12.0 - 2024-08-24 #

  • Updated lint rules for example
  • Updated lint rules for plugin
  • Updated documentation
  • Updated characteristic interaction UI

0.13.0 - 2024-08-31 #

  • Added method to get connected Bluetooth devices (currently only for iOS and macOS)

0.14.0 - 2025-01-25 #

0.15.0 - 2025-02-10 #

  • Added support for scanning BLE peripherals capable of accepting scan requests. Devices like this may spread their advertising data over multiple packets. This change allows app using this plugin to get the full data for this type of device.
  • Updated documentation

Breaking Changes #

  • Manufacturer data for the BleDevice class is now represented by a custom class rather than a string; this is the ManufacturerData class.
    • If you wish to continue using the manufacturer data as a string, you can use manufacturerData.payload to get the raw data.

0.16.0 - 2025-04-07 #

  • Added support for scanning BLE peripherals capable of accepting scan requests on macOS platforms.

0.16.1 - 2025-04-19 #

  • Updated Android Gradle plugin version and dependencies

0.16.2 - 2025-06-14 #

  • Updated example app localization dependencies
  • Fixed scan filtering by UUID for Android

0.17.0 - 2025-06-29 #

  • Updated filtering devices by name
  • Updated filtering devices by vendor ID
  • Updated filtering devices by manufacturer data
  • Added Bluetooth mocking tools for testing purposes
  • Added integration tests for the example app as references

0.18.0 - 2025-09-23 #

  • Updated Method Channel calls to be asynchronous
    • Async Method Channel calls allow for more robust error handling

0.19.0 - 2025-11-28 #

  • Implemented native Android Bluetooth permission handling
    • Added BluetoothPermissionsHandler class for Android platform
    • Automatic permission selection based on Android version (API 23-34)
    • Android 12+ (API 31+): Requests BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions
    • Android 10-11 (API 29-30): Requests ACCESS_FINE_LOCATION permission
    • Android 6-9 (API 23-28): Requests ACCESS_FINE_LOCATION permission
  • Fixed MissingPluginException for requestBluetoothPermissions and emitCurrentPermissionStatus on Android
  • Updated FlutterSplendidBlePlugin to implement ActivityAware for proper permission request handling
  • Fixed race condition in permission status emission to ensure listeners receive initial values
  • Updated AndroidManifest.xml with version-specific permission declarations
  • Updated example app to demonstrate proper permission request flow
  • Added unit tests for permission methods

Breaking Changes #

  • Android apps must now declare Bluetooth permissions in their AndroidManifest.xml (see documentation)

0.20.0 - 2025-12-30 #

  • Enhanced Android BLE write operations with improved reliability and asynchronous handling
    • Implemented sequential write operation queue to prevent race conditions
    • Added completion feedback for successful write operations
    • Updated Method Channel to return results after write operations complete
    • Improved error handling for Android API 33+
  • Fixed UUID filtering for BLE device scanning on Android
  • Fixed service UUID reporting accuracy on iOS
  • Code cleanup and optimization for better performance
  • Updated documentation for improved clarity

1.0.0 - 2026-01-22 #

Platform Synchronization #

  • Synchronized BLE APIs across Android, iOS, and macOS platforms for consistent behavior
  • Unified scan response handling across all platforms
  • Standardized manufacturer data reporting format
  • Consistent UUID filtering implementation delegated to Dart layer for cross-platform reliability
  • Updated iOS scan response handling to properly aggregate advertising and scan response data
  • Improved macOS deployment target compatibility

Enhanced BLE Operations #

  • Implemented MTU negotiation immediately after connection establishment for optimal data transfer
  • Added support for characteristic indications in addition to notifications
  • Enhanced descriptor write operations with proper completion awaiting
  • Improved subscription/unsubscription reliability with confirmation waiting
  • Added method to monitor device connection state changes in real-time
  • Enhanced disconnect handling and connection state management

Testing Infrastructure #

  • Created comprehensive ESP32-based BLE test device firmware for hardware-in-the-loop testing
    • Implements multiple test characteristics (read, write, notify, indicate, encrypted, MITM)
    • Provides manufacturer data in both advertisement and scan response packets
    • Visual feedback via LED matrix for connection status
    • Standardized test service with known UUIDs for validation
  • Developed dedicated test application for systematic BLE functionality validation
    • Automated test suite covering all plugin capabilities
    • Real-time test result reporting with pass/fail indicators
    • Tests for scanning, connection, service discovery, read/write operations, notifications, and pairing
    • Cross-platform validation (Android, iOS, macOS)
  • Added Makefile commands for firmware building and flashing
  • Integrated ESP32 test firmware as Git submodule

Reliability Improvements #

  • Enhanced permission and adapter status checking logic
  • Improved error handling throughout the plugin
  • Code cleanup and optimization across all platform implementations
  • Better handling of edge cases in BLE operations

Developer Experience #

  • Comprehensive hardware-in-the-loop testing capability
  • Clear visual feedback for test results
  • Detailed logging for debugging
  • Improved documentation for testing procedures

Breaking Changes #

None - this release maintains backward compatibility with 0.x versions while adding new capabilities.

6
likes
160
points
337
downloads

Documentation

API reference

Publisher

verified publishersplendidendeavors.com

Weekly Downloads

A comprehensive Flutter plugin for interacting with Bluetooth Low Energy (BLE) devices.

Repository (GitHub)
View/report issues
Contributing

License

BSD-3-Clause (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_splendid_ble

Packages that implement flutter_splendid_ble