diff --git a/AppScope/app.json5 b/AppScope/app.json5 index 9def6f660925b193aa4cb60415bf880644833a4f..1b224fbf8fb9880027d9e581d637f674a927a0ea 100644 --- a/AppScope/app.json5 +++ b/AppScope/app.json5 @@ -3,7 +3,7 @@ "bundleName": "cn.openharmony.fastble", "vendor": "example", "versionCode": 1000000, - "versionName": "2.0.2", + "versionName": "2.0.3", "icon": "$media:app_icon", "label": "$string:app_name" } diff --git a/CHANGELOG.md b/CHANGELOG.md index a61e575807ffda1f9590e539c89ba5f8f64f4087..c04e4f5cefdcbd786e58b6b6697409391caa813a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v2.0.3 + +- 修改调用setMtu时返回设置失败问题。 +- 修改调用write进行特征值写入时,部分设备收不到数据问题。 +- 修改调用write方法后,关闭手机蓝牙,然后打开重新扫描链接后再调用write方法,onCharacteristicChanged会多次回调。 +- 优化蓝牙扫描、连接、断开连接、以及监听事件注册的逻辑,添加异常捕获。 + ## v2.0.2 - 修改调用BleManager的notify接口后,在onNotifySuccess回调中再调用BleManager的write方法后,报错device is busy的BUG。 diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 index a7736afc7815d001eafeb948d9806198dc590174..0082d8ed2f5d3f0d390ada489d7a970274a97bb8 100644 --- a/entry/oh-package.json5 +++ b/entry/oh-package.json5 @@ -5,7 +5,7 @@ "name": "entry", "description": "Please describe the basic information.", "main": "", - "version": "2.0.2", + "version": "2.0.3", "dependencies": { "@ohos/fastble": "file:../library" } diff --git a/library/oh-package.json5 b/library/oh-package.json5 index df776012ad97d0fa8f5e5b1d10b5d8fbc3a999de..62396c852708b01baead32e7023cab83ab28ccfa 100644 --- a/library/oh-package.json5 +++ b/library/oh-package.json5 @@ -12,6 +12,6 @@ "description": "FastBle是一个处理蓝牙BLE设备的库,可以对蓝牙BLE设备进行过滤,扫描,连接,读取,写入等", "main": "Index.ets", "repository": "https://gitee.com/openharmony-sig/FastBle", - "version": "2.0.2", + "version": "2.0.3", "dependencies": {} } diff --git a/library/src/main/ets/bluetooth/BleBluetooth.ets b/library/src/main/ets/bluetooth/BleBluetooth.ets index b7b07d193d27c9b149f71ad6e310d4e5f395348f..ebeb9fb882d06c7e3286203e232b83b97f413657 100644 --- a/library/src/main/ets/bluetooth/BleBluetooth.ets +++ b/library/src/main/ets/bluetooth/BleBluetooth.ets @@ -179,20 +179,23 @@ export default class BleBluetooth { message.what = BleMsg.MSG_DISCOVER_SERVICES; this.mainHandler.sendMessageDelayed(message, 1000); } - return null; } - this.gattClientDevice = ble.createGattClientDevice(bleDevice.getMac()); try { - this.gattClientDevice.on('BLEConnectionStateChange', this.connectStateChangeCallback); - } catch (err) { - + this.gattClientDevice = ble.createGattClientDevice(bleDevice.getMac()); + } catch (e) { + BleLog.i("createGattClientDevice err: " +JSON.stringify(e)); } + try { + this.gattClientDevice?.on('BLEConnectionStateChange', this.connectStateChangeCallback); + } catch (err) { + BleLog.i("on BLEConnectionStateChange err: " +JSON.stringify(err)); + } try { - this.gattClientDevice.connect() + this.gattClientDevice?.connect() if (this.bleGattCallback != null) { this.bleGattCallback.onStartConnect(); } @@ -247,6 +250,7 @@ export default class BleBluetooth { try { this.gattClientDevice.disconnect(); } catch (e) { + BleLog.i("disconnect err: " +JSON.stringify(e)); } } } @@ -266,7 +270,11 @@ export default class BleBluetooth { private closeBluetoothGatt(): void { if (this.gattClientDevice != null) { - this.gattClientDevice.close(); + try { + this.gattClientDevice.close(); + } catch (e) { + BleLog.i("closeBluetoothGatt err: " +JSON.stringify(e)); + } } } diff --git a/library/src/main/ets/bluetooth/BleConnector.ets b/library/src/main/ets/bluetooth/BleConnector.ets index 8ebd4c2acdcec4b6a4e318eb2ce483e15a4bc259..681519f7a5c2ebc049ed75f30fee8be2922a7a94 100644 --- a/library/src/main/ets/bluetooth/BleConnector.ets +++ b/library/src/main/ets/bluetooth/BleConnector.ets @@ -29,6 +29,10 @@ import OtherException from '../exception/OtherException'; import TimeoutException from '../exception/TimeoutException'; import { Message, Handler } from '../utils/Handler'; import ble from '@ohos.bluetooth.ble'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { access } from '@kit.ConnectivityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import BleLog from '../utils/BleLog'; type UUID = string; type byte = number; @@ -40,11 +44,23 @@ export default class BleConnector { private mCharacteristic: ble.BLECharacteristic | null = null; private mBleBluetooth: BleBluetooth; private mHandler: Handler; + private bleMtuChangedCallback :BleMtuChangedCallback|null=null + private bleCharacteristicChangeCallBack: Callback|null=null + private TAG: string = "YTB BleConnector"; constructor(bleBluetooth: BleBluetooth) { this.mBleBluetooth = bleBluetooth; this.mBluetoothGatt = bleBluetooth.getBluetoothGatt(); this.mHandler = new BleConnectorHandler(this) + try { + access.on('stateChange', (data: access.BluetoothState) => { + if (data.valueOf()==0) { + this.mBluetoothGatt?.off("BLECharacteristicChange") + } + }); + } catch (err) { + console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); + } } private withUUID(serviceUUID: UUID, characteristicUUID: UUID): BleConnector { @@ -81,8 +97,7 @@ export default class BleConnector { */ public enableCharacteristicNotify(bleNotifyCallback: BleNotifyCallback, uuid_notify: string, userCharacteristicDescriptor: boolean): void { - if (this.mCharacteristic != null && this.mBluetoothGatt != null - ) { + if (this.mCharacteristic != null && this.mBluetoothGatt != null) { this.handleCharacteristicNotifyCallback(bleNotifyCallback, uuid_notify); this.setCharacteristicNotification(this.mBluetoothGatt, this.mCharacteristic, userCharacteristicDescriptor, true, bleNotifyCallback); @@ -266,9 +281,7 @@ export default class BleConnector { return; } - if (this.mCharacteristic == null - /*|| (this.mCharacteristic.getProperties() & (bluetooth.BLECharacteristic.PROPERTY_WRITE | bluetooth.BLECharacteristic.PROPERTY_WRITE_NO_RESPONSE)) == 0*/ - ) { + if (this.mCharacteristic == null) { if (bleWriteCallback != null) { bleWriteCallback.onWriteFailure(new OtherException("this characteristic not support write!")); } @@ -280,7 +293,11 @@ export default class BleConnector { console.info("BleConnetor.writeCharacteristic calling gatt.writeCharacteristic"); if (this.mBluetoothGatt !== null) { try { - this.mBluetoothGatt.writeCharacteristicValue(this.mCharacteristic, ble.GattWriteType.WRITE) + if (this.mCharacteristic.properties?.writeNoResponse) { + this.mBluetoothGatt.writeCharacteristicValue(this.mCharacteristic, ble.GattWriteType.WRITE_NO_RESPONSE) + }else { + this.mBluetoothGatt.writeCharacteristicValue(this.mCharacteristic, ble.GattWriteType.WRITE) + } if (bleWriteCallback != null) { this.writeMsgInit(); bleWriteCallback.onWriteSuccess(data.length, data.length, data); @@ -299,20 +316,23 @@ export default class BleConnector { * read */ public readCharacteristic(bleReadCallback: BleReadCallback, uuid_read: string): void { - if (this.mCharacteristic != null - /*&& (this.mCharacteristic.getProperties() & bluetooth.BLECharacteristic.PROPERTY_READ) > 0*/ - ) { + if (this.mCharacteristic != null) { this.handleCharacteristicReadCallback(bleReadCallback, uuid_read); - this.mBluetoothGatt?.readCharacteristicValue(this.mCharacteristic, (err, characteristic: ble.BLECharacteristic) => { - this.readMsgInit(); - if (bleReadCallback != null) { - if (!err) { - bleReadCallback.onReadSuccess(new Uint8Array(characteristic.characteristicValue)); - } else { - bleReadCallback.onReadFailure(new OtherException("gatt readCharacteristic fail:" + err.message)); - } - } - }); + try { + this.mBluetoothGatt?.readCharacteristicValue(this.mCharacteristic, + (err, characteristic: ble.BLECharacteristic) => { + this.readMsgInit(); + if (bleReadCallback != null) { + if (!err) { + bleReadCallback.onReadSuccess(new Uint8Array(characteristic.characteristicValue)); + } else { + bleReadCallback.onReadFailure(new OtherException("gatt readCharacteristic fail:" + err.message)); + } + } + }); + } catch (e) { + BleLog.i("readCharacteristicValue err: " +JSON.stringify(e)); + } } else { if (bleReadCallback != null) { bleReadCallback.onReadFailure(new OtherException("this characteristic not support read!")); @@ -325,35 +345,44 @@ export default class BleConnector { */ public readRemoteRssi(bleRssiCallback: BleRssiCallback): void { this.handleRSSIReadCallback(bleRssiCallback); - this.mBluetoothGatt?.getRssiValue((err, number) => { - this.rssiMsgInit(); - if (bleRssiCallback != null) { - if (!err) { - bleRssiCallback.onRssiSuccess(number); - } else { - bleRssiCallback.onRssiFailure(new OtherException("gatt readRemoteRssi fail:" + err.message)); + try { + this.mBluetoothGatt?.getRssiValue((err, number) => { + this.rssiMsgInit(); + if (bleRssiCallback != null) { + if (!err) { + bleRssiCallback.onRssiSuccess(number); + } else { + bleRssiCallback.onRssiFailure(new OtherException("gatt readRemoteRssi fail:" + err.message)); + } } - } - }); + }); + } catch (e) { + BleLog.i("getRssiValue err: " +JSON.stringify(e)); + } } /** * set mtu */ public setMtu(requiredMtu: number, bleMtuChangedCallback: BleMtuChangedCallback): void { + this.bleMtuChangedCallback = bleMtuChangedCallback; this.handleSetMtuCallback(bleMtuChangedCallback); - try { - if (this.mBluetoothGatt !== null) { + if (!!this.mBluetoothGatt) { this.mBluetoothGatt.setBLEMtuSize(requiredMtu) + bleMtuChangedCallback.setHandler(this.mHandler); + this.mBleBluetooth.addMtuChangedCallback(bleMtuChangedCallback); + let message = this.mHandler.obtainMessage(BleMsg.MSG_SET_MTU_RESULT, bleMtuChangedCallback); + let bundle: Map = new Map(); + bundle.set(BleMsg.KEY_SET_MTU_BUNDLE_VALUE, requiredMtu); + message.setData(bundle); + this.mHandler.sendMessage(message); } } catch (e) { - this.mtuChangedMsgInit(); if (bleMtuChangedCallback != null) { bleMtuChangedCallback.onSetMTUFailure(new OtherException("gatt requestMtu fail")); } - } } @@ -646,14 +675,9 @@ class BleConnectorHandler extends Handler { this.bleConnector.mtuChangedMsgInit(); let mtuChangedCallback: BleMtuChangedCallback = msg.obj as BleMtuChangedCallback; - let status: number = msg.getData().get(BleMsg.KEY_SET_MTU_BUNDLE_STATUS); let value: number = msg.getData().get(BleMsg.KEY_SET_MTU_BUNDLE_VALUE); if (mtuChangedCallback != null) { - if (status == 0) { mtuChangedCallback.onMtuChanged(value); - } else { - mtuChangedCallback.onSetMTUFailure(new GattException(status)); - } } break; } diff --git a/library/src/main/ets/scan/BleScanPresenter.ets b/library/src/main/ets/scan/BleScanPresenter.ets index 84991c14089edce63beaac046e9ba72d64c4d857..531094a144ad16556f222c6d0d70fdac8ff59f49 100644 --- a/library/src/main/ets/scan/BleScanPresenter.ets +++ b/library/src/main/ets/scan/BleScanPresenter.ets @@ -52,12 +52,16 @@ abstract class BleScanPresenter { private handleResult(bleDevice: BleDevice): void { this.onLeScan(bleDevice); - let gattClient = ble.createGattClientDevice(bleDevice.getMac()); - let that = this - gattClient.getDeviceName((err, data) => { - bleDevice.setName(data); - that.checkDevice(bleDevice); - }) + try { + let gattClient = ble.createGattClientDevice(bleDevice.getMac()); + let that = this + gattClient.getDeviceName((err, data) => { + bleDevice.setName(data); + that.checkDevice(bleDevice); + }) + } catch (e) { + BleLog.i("BleScanPresenter getDeviceName err: " +JSON.stringify(e)); + } } public handleScanResults(data: Array): void { diff --git a/library/src/main/ets/scan/BleScanner.ets b/library/src/main/ets/scan/BleScanner.ets index f18843212ffb46a8f397b515c895d5d367da81a1..4b9fc5411a3e5c5cfb0efc8002e728edf90642be 100644 --- a/library/src/main/ets/scan/BleScanner.ets +++ b/library/src/main/ets/scan/BleScanner.ets @@ -78,7 +78,11 @@ export default class BleScanner { if (BleManager.MOCK_DEVICE) { BleManager.mockBluetooth.onScan(this.callback); } else { - ble.on('BLEDeviceFind', this.callback); + try { + ble.on('BLEDeviceFind', this.callback); + } catch (e) { + BleLog.i("on BLEDeviceFind err: " +JSON.stringify(e)); + } } console.info("after on") @@ -100,12 +104,15 @@ export default class BleScanner { if (BleManager.MOCK_DEVICE) { BleManager.mockBluetooth.startBLEScan(); } else { - if (filterArry.length == 0) { - ble.startBLEScan(null, scanOption); - } else { - ble.startBLEScan(filterArry, scanOption); + try { + if (filterArry.length == 0) { + ble.startBLEScan(null, scanOption); + } else { + ble.startBLEScan(filterArry, scanOption); + } + } catch (e) { + BleLog.i("startBLEScan err: " +JSON.stringify(e)); } - } this.mBleScanState = BleScanState.STATE_SCANNING; @@ -116,10 +123,18 @@ export default class BleScanner { if (BleManager.MOCK_DEVICE) { BleManager.mockBluetooth.stopBLEScan(); } else { - ble.stopBLEScan(); + try { + ble.stopBLEScan(); + } catch (e) { + BleLog.i("stopBLEScan err: " +JSON.stringify(e)); + } } this.mBleScanState = BleScanState.STATE_IDLE; - ble.off('BLEDeviceFind',this.callback) + try { + ble.off('BLEDeviceFind', this.callback) + } catch (e) { + BleLog.i("off BLEDeviceFind err: " +JSON.stringify(e)); + } this.mBleScanPresenter.notifyScanStopped(); }