Improve Apple, Android and Windows (#40)
* Cleanup connection * Reverse search list * Bump version * Fix Android serviceUuids in scanResults * Fix typo * Improve cleanup on apple * Improve Apple reconnection and service discovery * Persist long scan result name on Windows Co-authored-by: navidecklabs <navidecklabs@users.noreply.github.com> * Update changelog --------- Co-authored-by: Rohit Sangwan <rohitsangwan647@gmail.com> Co-authored-by: navidecklabs <navidecklabs@users.noreply.github.com>
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
## 0.9.9
|
||||
* Improve service discovery on Apple
|
||||
* Improve reconnection on Apple
|
||||
* Persist long scan result name on Windows
|
||||
* Fix Android serviceUuids in scanResults
|
||||
* Example app improvements
|
||||
|
||||
## 0.9.8
|
||||
* Improve manufacturer data discovery on Windows
|
||||
* Example app improvements
|
||||
|
||||
@@ -238,7 +238,7 @@ fun BluetoothDevice.removeBond() {
|
||||
try {
|
||||
javaClass.getMethod("removeBond").invoke(this)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Removing bond has been failed. ${e.message}")
|
||||
Log.e(TAG, "Removing bond failed. ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -665,6 +665,15 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
|
||||
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||
// Log.v(TAG, "onScanResult: $result")
|
||||
var serviceUuids: Array<String> = arrayOf<String>()
|
||||
result.device.uuids?.forEach {
|
||||
serviceUuids += it.uuid.toString()
|
||||
}
|
||||
result.scanRecord?.serviceUuids?.forEach {
|
||||
if (!serviceUuids.contains(it.uuid.toString())) {
|
||||
serviceUuids += it.uuid.toString()
|
||||
}
|
||||
}
|
||||
mainThreadHandler?.post {
|
||||
callbackChannel?.onScanResult(
|
||||
UniversalBleScanResult(
|
||||
@@ -673,8 +682,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
isPaired = result.device.bondState == BOND_BONDED,
|
||||
manufacturerDataHead = result.manufacturerDataHead,
|
||||
rssi = result.rssi.toLong(),
|
||||
services = result.device.uuids?.map { it.uuid?.toString() ?: "" }
|
||||
?: emptyList()
|
||||
services = serviceUuids.toList()
|
||||
)
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -95,24 +95,51 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
|
||||
func cleanUpConnection(deviceId: String) {
|
||||
characteristicReadFutures.removeAll { future in
|
||||
future.deviceId == deviceId
|
||||
if future.deviceId == deviceId {
|
||||
future.result(
|
||||
Result.failure(FlutterError(code: "DeviceDisconnected", message: "Device Disconnected", details: nil))
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
discoverServicesFutures.removeAll { future in
|
||||
future.deviceId == deviceId
|
||||
if future.deviceId == deviceId {
|
||||
future.result(
|
||||
Result.failure(FlutterError(code: "DeviceDisconnected", message: "Device Disconnected", details: nil))
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
discoveredServicesProgressMap[deviceId] = nil
|
||||
}
|
||||
|
||||
func discoverServices(deviceId: String, completion: @escaping (Result<[UniversalBleService], Error>) -> Void) {
|
||||
guard let peripheral = discoveredPeripherals[deviceId] else {
|
||||
completion(Result.failure(
|
||||
FlutterError(code: "IllegalArgument", message: "Unknown deviceId:\(self)", details: nil)))
|
||||
completion(
|
||||
Result.failure(FlutterError(code: "IllegalArgument", message: "Unknown deviceId:\(self)", details: nil))
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if discoveredServicesProgressMap[deviceId] != nil {
|
||||
completion(Result.failure(FlutterError(code: "AlreadyInProgress", message: "Services discovery already in progress for :\(deviceId)", details: nil)))
|
||||
print("Services discovery already in progress for :\(deviceId), waiting for completion.")
|
||||
discoverServicesFutures.append(DiscoverServicesFuture(deviceId: deviceId, result: completion))
|
||||
return
|
||||
}
|
||||
|
||||
if let cachedServices = peripheral.services {
|
||||
// If services already discovered no need to discover again
|
||||
if !cachedServices.isEmpty {
|
||||
// print("Services already cached for this peripheral")
|
||||
discoverServicesFutures.append(DiscoverServicesFuture(deviceId: deviceId, result: completion))
|
||||
self.peripheral(peripheral, didDiscoverServices: nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
peripheral.discoverServices(nil)
|
||||
discoverServicesFutures.append(DiscoverServicesFuture(deviceId: deviceId, result: completion))
|
||||
}
|
||||
@@ -270,6 +297,8 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
|
||||
public func centralManager(_: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error _: Error?) {
|
||||
callbackChannel.onConnectionChanged(deviceId: peripheral.uuid.uuidString, state: BlueConnectionState.disconnected.rawValue) { _ in }
|
||||
// Cleanup on disconnect
|
||||
cleanUpConnection(deviceId: peripheral.uuid.uuidString)
|
||||
}
|
||||
|
||||
public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices _: Error?) {
|
||||
@@ -280,6 +309,12 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
}
|
||||
discoveredServicesProgressMap[deviceId] = services.map { UniversalBleService(uuid: $0.uuid.uuidString, characteristics: nil) }
|
||||
for service in services {
|
||||
if let cachedChar = service.characteristics {
|
||||
if !cachedChar.isEmpty {
|
||||
self.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: nil)
|
||||
continue
|
||||
}
|
||||
}
|
||||
peripheral.discoverCharacteristics(nil, for: service)
|
||||
}
|
||||
}
|
||||
@@ -303,7 +338,7 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral
|
||||
}
|
||||
|
||||
public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
|
||||
print("peripheral:didWriteValueForCharacteristic \(characteristic.uuid.uuidStr) error: \(String(describing: error))")
|
||||
// print("peripheral:didWriteValueForCharacteristic \(characteristic.uuid.uuidStr) error: \(String(describing: error))")
|
||||
// Update futures for writeValue
|
||||
characteristicWriteFutures.removeAll { future in
|
||||
if future.deviceId == peripheral.uuid.uuidString && future.characteristicId == characteristic.uuid.uuidStr && future.serviceId == characteristic.service?.uuid.uuidStr {
|
||||
|
||||
@@ -225,7 +225,8 @@ class _MyAppState extends State<MyApp> {
|
||||
itemCount: _scanResults.length,
|
||||
separatorBuilder: (context, index) => const Divider(),
|
||||
itemBuilder: (context, index) {
|
||||
BleScanResult scanResult = _scanResults[index];
|
||||
BleScanResult scanResult =
|
||||
_scanResults[_scanResults.length - index - 1];
|
||||
return ScannedItemWidget(
|
||||
scanResult: scanResult,
|
||||
onTap: () {
|
||||
|
||||
@@ -26,4 +26,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
|
||||
|
||||
COCOAPODS: 1.14.3
|
||||
COCOAPODS: 1.15.2
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0920;
|
||||
LastUpgradeCheck = 1430;
|
||||
LastUpgradeCheck = 1510;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
331C80D4294CF70F00263BE5 = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1430"
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
name: universal_ble
|
||||
description: A cross-platform (Android/iOS/macOS/Windows/Linux/Web) Bluetooth Low Energy (BLE) plugin for Flutter
|
||||
version: 0.9.8
|
||||
version: 0.9.9
|
||||
homepage: https://navideck.com
|
||||
repository: https://github.com/Navideck/universal_ble
|
||||
issue_tracker: https://github.com/Navideck/universal_ble/issues
|
||||
|
||||
@@ -554,26 +554,37 @@ namespace universal_ble
|
||||
auto it = scanResults.find(scanResult.device_id());
|
||||
if (it != scanResults.end())
|
||||
{
|
||||
UniversalBleScanResult &existingScanResult = it->second;
|
||||
UniversalBleScanResult ¤tScanResult = it->second;
|
||||
bool shouldUpdate = false;
|
||||
if ((scanResult.name() == nullptr || scanResult.name()->empty()) && (existingScanResult.name() != nullptr && !existingScanResult.name()->empty()))
|
||||
|
||||
// Check if current scanResult name is longer than the received scanResult name
|
||||
if (scanResult.name() != nullptr && !scanResult.name()->empty() && currentScanResult.name() != nullptr && !currentScanResult.name()->empty())
|
||||
{
|
||||
scanResult.set_name(*existingScanResult.name());
|
||||
if (currentScanResult.name()->size() > scanResult.name()->size())
|
||||
{
|
||||
scanResult.set_name(*currentScanResult.name());
|
||||
}
|
||||
}
|
||||
|
||||
if ((scanResult.name() == nullptr || scanResult.name()->empty()) && (currentScanResult.name() != nullptr && !currentScanResult.name()->empty()))
|
||||
{
|
||||
scanResult.set_name(*currentScanResult.name());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.is_paired() == nullptr && existingScanResult.is_paired() != nullptr)
|
||||
|
||||
if (scanResult.is_paired() == nullptr && currentScanResult.is_paired() != nullptr)
|
||||
{
|
||||
scanResult.set_is_paired(existingScanResult.is_paired());
|
||||
scanResult.set_is_paired(currentScanResult.is_paired());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.manufacturer_data_head() == nullptr && existingScanResult.manufacturer_data_head() != nullptr)
|
||||
if (scanResult.manufacturer_data_head() == nullptr && currentScanResult.manufacturer_data_head() != nullptr)
|
||||
{
|
||||
scanResult.set_manufacturer_data_head(existingScanResult.manufacturer_data_head());
|
||||
scanResult.set_manufacturer_data_head(currentScanResult.manufacturer_data_head());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
if (scanResult.services() == nullptr && existingScanResult.services() != nullptr)
|
||||
if (scanResult.services() == nullptr && currentScanResult.services() != nullptr)
|
||||
{
|
||||
scanResult.set_services(existingScanResult.services());
|
||||
scanResult.set_services(currentScanResult.services());
|
||||
shouldUpdate = true;
|
||||
}
|
||||
|
||||
@@ -581,8 +592,8 @@ namespace universal_ble
|
||||
if (!shouldUpdate)
|
||||
return;
|
||||
|
||||
// update the existing scan result
|
||||
existingScanResult = scanResult;
|
||||
// update the current scan result
|
||||
currentScanResult = scanResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user