2.0.1 (#10)
* fix: 修复 iOS 和 macOS 断开后 GATT 被清理导致操作无法完成的问题 * fix: 调整 GATT 缓存 * fix: 修改 iOS 蓝牙使用描述 * fix: 修复无法通过设备地址生成 UUID 的问题,修复由于 bluez 未重写 hashCode 和 equals 导致无法比较缓存实例的问题 * fix: 修改版本信息 * fix: 修复BUG * fix: 调整示例程序 * fix: 优化代码 * fix: 修改版本号 * fix: 更新 REDEME.md * fix: 更新依赖项 * fix: 项目调整 --------- Co-authored-by: jetson2 <jetson2@const.cc>
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
## 2.0.1
|
||||
|
||||
- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS.
|
||||
- Fix the issue that create UUID form peripheral's address failed on Linux.
|
||||
- Fix the issue that instance match failed on Linux.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
- Rewrite the whole project with federated plugins.
|
||||
|
@ -282,11 +282,11 @@ interface MyCentralControllerHostApi {
|
||||
fun getServices(myPeripheralKey: Long): List<MyGattServiceArgs>
|
||||
fun getCharacteristics(myServiceKey: Long): List<MyGattCharacteristicArgs>
|
||||
fun getDescriptors(myCharacteristicKey: Long): List<MyGattDescriptorArgs>
|
||||
fun readCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, callback: (Result<ByteArray>) -> Unit)
|
||||
fun writeCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result<Unit>) -> Unit)
|
||||
fun notifyCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result<Unit>) -> Unit)
|
||||
fun readDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, callback: (Result<ByteArray>) -> Unit)
|
||||
fun writeDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result<Unit>) -> Unit)
|
||||
fun readCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, callback: (Result<ByteArray>) -> Unit)
|
||||
fun writeCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result<Unit>) -> Unit)
|
||||
fun notifyCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result<Unit>) -> Unit)
|
||||
fun readDescriptor(myPeripheralKey: Long, myCharacteristicKey: Long, myDescriptorKey: Long, callback: (Result<ByteArray>) -> Unit)
|
||||
fun writeDescriptor(myPeripheralKey: Long, myCharacteristicKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result<Unit>) -> Unit)
|
||||
|
||||
companion object {
|
||||
/** The codec used by MyCentralControllerHostApi. */
|
||||
@ -482,8 +482,9 @@ interface MyCentralControllerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.readCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg) { result: Result<ByteArray> ->
|
||||
val myServiceKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.readCharacteristic(myPeripheralKeyArg, myServiceKeyArg, myCharacteristicKeyArg) { result: Result<ByteArray> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
@ -503,10 +504,11 @@ interface MyCentralControllerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val valueArg = args[2] as ByteArray
|
||||
val myTypeNumberArg = args[3].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.writeCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg, valueArg, myTypeNumberArg) { result: Result<Unit> ->
|
||||
val myServiceKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
val valueArg = args[3] as ByteArray
|
||||
val myTypeNumberArg = args[4].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.writeCharacteristic(myPeripheralKeyArg, myServiceKeyArg, myCharacteristicKeyArg, valueArg, myTypeNumberArg) { result: Result<Unit> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
@ -525,9 +527,10 @@ interface MyCentralControllerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val stateArg = args[2] as Boolean
|
||||
api.notifyCharacteristic(myPeripheralKeyArg, myCharacteristicKeyArg, stateArg) { result: Result<Unit> ->
|
||||
val myServiceKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myCharacteristicKeyArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
val stateArg = args[3] as Boolean
|
||||
api.notifyCharacteristic(myPeripheralKeyArg, myServiceKeyArg, myCharacteristicKeyArg, stateArg) { result: Result<Unit> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
@ -546,8 +549,9 @@ interface MyCentralControllerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myDescriptorKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.readDescriptor(myPeripheralKeyArg, myDescriptorKeyArg) { result: Result<ByteArray> ->
|
||||
val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myDescriptorKeyArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.readDescriptor(myPeripheralKeyArg, myCharacteristicKeyArg, myDescriptorKeyArg) { result: Result<ByteArray> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
@ -567,9 +571,10 @@ interface MyCentralControllerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myDescriptorKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val valueArg = args[2] as ByteArray
|
||||
api.writeDescriptor(myPeripheralKeyArg, myDescriptorKeyArg, valueArg) { result: Result<Unit> ->
|
||||
val myCharacteristicKeyArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
val myDescriptorKeyArg = args[2].let { if (it is Int) it.toLong() else it as Long }
|
||||
val valueArg = args[3] as ByteArray
|
||||
api.writeDescriptor(myPeripheralKeyArg, myCharacteristicKeyArg, myDescriptorKeyArg, valueArg) { result: Result<Unit> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
|
@ -27,7 +27,8 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
companion object {
|
||||
// const val DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xff.toByte()
|
||||
private const val REQUEST_CODE = 443
|
||||
// private val UUID_HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb")
|
||||
|
||||
// private val UUID_HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb")
|
||||
private val UUID_CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")
|
||||
}
|
||||
|
||||
@ -44,11 +45,11 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
private val myScanCallback = MyScanCallback(this)
|
||||
private val myGattCallback = MyBluetoothGattCallback(this, executor)
|
||||
|
||||
private val devices = mutableMapOf<Int, BluetoothDevice>()
|
||||
private val gatts = mutableMapOf<Int, BluetoothGatt>()
|
||||
private val services = mutableMapOf<Int, BluetoothGattService>()
|
||||
private val characteristics = mutableMapOf<Int, BluetoothGattCharacteristic>()
|
||||
private val descriptors = mutableMapOf<Int, BluetoothGattDescriptor>()
|
||||
private val cachedDevices = mutableMapOf<Int, BluetoothDevice>()
|
||||
private val cachedGATTs = mutableMapOf<Int, BluetoothGatt>()
|
||||
private val cachedServices = mutableMapOf<Int, Map<Int, BluetoothGattService>>()
|
||||
private val cachedCharacteristics = mutableMapOf<Int, Map<Int, BluetoothGattCharacteristic>>()
|
||||
private val cachedDescriptors = mutableMapOf<Int, Map<Int, BluetoothGattDescriptor>>()
|
||||
|
||||
private var registered = false
|
||||
private var discovering = false
|
||||
@ -95,14 +96,14 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
if (discovering) {
|
||||
stopDiscovery()
|
||||
}
|
||||
for (gatt in gatts.values) {
|
||||
for (gatt in cachedGATTs.values) {
|
||||
gatt.disconnect()
|
||||
}
|
||||
devices.clear()
|
||||
gatts.clear()
|
||||
services.clear()
|
||||
characteristics.clear()
|
||||
descriptors.clear()
|
||||
cachedDevices.clear()
|
||||
cachedGATTs.clear()
|
||||
cachedServices.clear()
|
||||
cachedCharacteristics.clear()
|
||||
cachedDescriptors.clear()
|
||||
}
|
||||
|
||||
private fun register() {
|
||||
@ -148,9 +149,9 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val device = devices[deviceKey] as BluetoothDevice
|
||||
val device = cachedDevices[deviceKey] as BluetoothDevice
|
||||
val autoConnect = false
|
||||
gatts[deviceKey] = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
cachedGATTs[deviceKey] = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val transport = BluetoothDevice.TRANSPORT_LE
|
||||
device.connectGatt(context, autoConnect, myGattCallback, transport)
|
||||
} else {
|
||||
@ -169,7 +170,7 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
gatt.disconnect()
|
||||
disconnectCallbacks[deviceKey] = callback
|
||||
} catch (e: Throwable) {
|
||||
@ -184,7 +185,7 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val discovering = gatt.discoverServices()
|
||||
if (!discovering) {
|
||||
throw IllegalStateException()
|
||||
@ -197,53 +198,35 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
|
||||
override fun getServices(myPeripheralKey: Long): List<MyGattServiceArgs> {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val services = gatt.services
|
||||
return services.map { service ->
|
||||
val serviceKey = service.hashCode()
|
||||
if (this.services[serviceKey] == null) {
|
||||
this.services[serviceKey] = service
|
||||
}
|
||||
return@map service.toMyArgs()
|
||||
}
|
||||
val services = cachedServices[deviceKey] ?: throw IllegalStateException()
|
||||
return services.values.map { service -> service.toMyArgs() }
|
||||
}
|
||||
|
||||
override fun getCharacteristics(myServiceKey: Long): List<MyGattCharacteristicArgs> {
|
||||
val serviceKey = myServiceKey.toInt()
|
||||
val service = services[serviceKey] as BluetoothGattService
|
||||
val characteristics = service.characteristics
|
||||
return characteristics.map { characteristic ->
|
||||
val characteristicKey = characteristic.hashCode()
|
||||
if (this.characteristics[characteristicKey] == null) {
|
||||
this.characteristics[characteristicKey] = characteristic
|
||||
}
|
||||
return@map characteristic.toMyArgs()
|
||||
}
|
||||
val characteristics = cachedCharacteristics[serviceKey] ?: throw IllegalStateException()
|
||||
return characteristics.values.map { characteristic -> characteristic.toMyArgs() }
|
||||
}
|
||||
|
||||
override fun getDescriptors(myCharacteristicKey: Long): List<MyGattDescriptorArgs> {
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val descriptors = characteristic.descriptors
|
||||
return descriptors.map { descriptor ->
|
||||
val descriptorKey = descriptor.hashCode()
|
||||
if (this.descriptors[descriptorKey] == null) {
|
||||
this.descriptors[descriptorKey] = descriptor
|
||||
}
|
||||
return@map descriptor.toMyArgs()
|
||||
}
|
||||
val descriptors = cachedDescriptors[characteristicKey] ?: throw IllegalStateException()
|
||||
return descriptors.values.map { descriptor -> descriptor.toMyArgs() }
|
||||
}
|
||||
|
||||
override fun readCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, callback: (Result<ByteArray>) -> Unit) {
|
||||
override fun readCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, callback: (Result<ByteArray>) -> Unit) {
|
||||
try {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val serviceKey = myServiceKey.toInt()
|
||||
val characteristics = cachedCharacteristics[serviceKey]
|
||||
?: throw IllegalArgumentException()
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val unfinishedCallback = readCharacteristicCallbacks[characteristicKey]
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val reading = gatt.readCharacteristic(characteristic)
|
||||
if (!reading) {
|
||||
throw IllegalStateException()
|
||||
@ -254,16 +237,19 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result<Unit>) -> Unit) {
|
||||
override fun writeCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, value: ByteArray, myTypeNumber: Long, callback: (Result<Unit>) -> Unit) {
|
||||
try {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val serviceKey = myServiceKey.toInt()
|
||||
val characteristics = cachedCharacteristics[serviceKey]
|
||||
?: throw IllegalArgumentException()
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val unfinishedCallback = writeCharacteristicCallbacks[characteristicKey]
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val myTypeArgs = myTypeNumber.toMyGattCharacteristicTypeArgs()
|
||||
val writeType = myTypeArgs.toType()
|
||||
characteristic.value = value
|
||||
@ -278,11 +264,14 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
}
|
||||
}
|
||||
|
||||
override fun notifyCharacteristic(myPeripheralKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result<Unit>) -> Unit) {
|
||||
override fun notifyCharacteristic(myPeripheralKey: Long, myServiceKey: Long, myCharacteristicKey: Long, state: Boolean, callback: (Result<Unit>) -> Unit) {
|
||||
try {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val serviceKey = myServiceKey.toInt()
|
||||
val characteristics = cachedCharacteristics[serviceKey]
|
||||
?: throw IllegalArgumentException()
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val characteristic = characteristics[characteristicKey] as BluetoothGattCharacteristic
|
||||
val notifying = gatt.setCharacteristicNotification(characteristic, state)
|
||||
if (!notifying) {
|
||||
@ -314,16 +303,19 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
}
|
||||
}
|
||||
|
||||
override fun readDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, callback: (Result<ByteArray>) -> Unit) {
|
||||
override fun readDescriptor(myPeripheralKey: Long, myCharacteristicKey: Long, myDescriptorKey: Long, callback: (Result<ByteArray>) -> Unit) {
|
||||
try {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val descriptors = cachedDescriptors[characteristicKey]
|
||||
?: throw IllegalArgumentException()
|
||||
val descriptorKey = myDescriptorKey.toInt()
|
||||
val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor
|
||||
val unfinishedCallback = readDescriptorCallbacks[descriptorKey]
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor
|
||||
val reading = gatt.readDescriptor(descriptor)
|
||||
if (!reading) {
|
||||
throw IllegalStateException()
|
||||
@ -334,16 +326,19 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeDescriptor(myPeripheralKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result<Unit>) -> Unit) {
|
||||
override fun writeDescriptor(myPeripheralKey: Long, myCharacteristicKey: Long, myDescriptorKey: Long, value: ByteArray, callback: (Result<Unit>) -> Unit) {
|
||||
try {
|
||||
val deviceKey = myPeripheralKey.toInt()
|
||||
val gatt = cachedGATTs[deviceKey] as BluetoothGatt
|
||||
val characteristicKey = myCharacteristicKey.toInt()
|
||||
val descriptors = cachedDescriptors[characteristicKey]
|
||||
?: throw IllegalArgumentException()
|
||||
val descriptorKey = myDescriptorKey.toInt()
|
||||
val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor
|
||||
val unfinishedCallback = writeDescriptorCallbacks[descriptorKey]
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = gatts[deviceKey] as BluetoothGatt
|
||||
val descriptor = descriptors[descriptorKey] as BluetoothGattDescriptor
|
||||
descriptor.value = value
|
||||
val writing = gatt.writeDescriptor(descriptor)
|
||||
if (!writing) {
|
||||
@ -407,9 +402,7 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
fun onScanResult(result: ScanResult) {
|
||||
val device = result.device
|
||||
val deviceKey = device.hashCode()
|
||||
if (devices[deviceKey] == null) {
|
||||
devices[deviceKey] = device
|
||||
}
|
||||
cachedDevices[deviceKey] = device
|
||||
val myPeripheralArgs = device.toMyArgs()
|
||||
val rssi = result.rssi.toLong()
|
||||
val myAdvertisementArgs = result.myAdvertisementArgs
|
||||
@ -422,27 +415,28 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
val myPeripheralKey = deviceKey.toLong()
|
||||
if (newState != BluetoothProfile.STATE_CONNECTED) {
|
||||
gatt.close()
|
||||
gatts.remove(deviceKey)
|
||||
cachedGATTs.remove(deviceKey)
|
||||
val error = IllegalStateException("GATT is disconnected with status: $status")
|
||||
val discoverGattCallback = discoverGattCallbacks.remove(deviceKey)
|
||||
if (discoverGattCallback != null) {
|
||||
discoverGattCallback(Result.failure(error))
|
||||
}
|
||||
for (service in gatt.services) {
|
||||
for (characteristic in service.characteristics) {
|
||||
val characteristicKey = characteristic.hashCode()
|
||||
val readCharacteristicCallback = readCharacteristicCallbacks.remove(characteristicKey)
|
||||
val writeCharacteristicCallback = writeCharacteristicCallbacks.remove(characteristicKey)
|
||||
val services = cachedServices[deviceKey] ?: emptyMap()
|
||||
for (service in services) {
|
||||
val characteristics = cachedCharacteristics[service.key] ?: emptyMap()
|
||||
for (characteristic in characteristics) {
|
||||
val readCharacteristicCallback = readCharacteristicCallbacks.remove(characteristic.key)
|
||||
val writeCharacteristicCallback = writeCharacteristicCallbacks.remove(characteristic.key)
|
||||
if (readCharacteristicCallback != null) {
|
||||
readCharacteristicCallback(Result.failure(error))
|
||||
}
|
||||
if (writeCharacteristicCallback != null) {
|
||||
writeCharacteristicCallback(Result.failure(error))
|
||||
}
|
||||
for (descriptor in characteristic.descriptors) {
|
||||
val descriptorKey = descriptor.hashCode()
|
||||
val readDescriptorCallback = readDescriptorCallbacks.remove(descriptorKey)
|
||||
val writeDescriptorCallback = writeDescriptorCallbacks.remove(descriptorKey)
|
||||
val descriptors = cachedDescriptors[characteristic.key] ?: emptyMap()
|
||||
for (descriptor in descriptors) {
|
||||
val readDescriptorCallback = readDescriptorCallbacks.remove(descriptor.key)
|
||||
val writeDescriptorCallback = writeDescriptorCallbacks.remove(descriptor.key)
|
||||
if (readDescriptorCallback != null) {
|
||||
readDescriptorCallback(Result.failure(error))
|
||||
}
|
||||
@ -490,6 +484,24 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM
|
||||
val deviceKey = device.hashCode()
|
||||
val callback = discoverGattCallbacks.remove(deviceKey) ?: return
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
val cachedServices = mutableMapOf<Int, BluetoothGattService>()
|
||||
for (service in gatt.services) {
|
||||
val serviceKey = service.hashCode()
|
||||
cachedServices[serviceKey] = service
|
||||
val cachedCharacteristics = mutableMapOf<Int, BluetoothGattCharacteristic>()
|
||||
for (characteristic in service.characteristics) {
|
||||
val characteristicKey = characteristic.hashCode()
|
||||
cachedCharacteristics[characteristicKey] = characteristic
|
||||
val cachedDescriptors = mutableMapOf<Int, BluetoothGattDescriptor>()
|
||||
for (descriptor in characteristic.descriptors) {
|
||||
val descriptorKey = descriptor.hashCode()
|
||||
cachedDescriptors[descriptorKey] = descriptor
|
||||
}
|
||||
this.cachedDescriptors[characteristicKey] = cachedDescriptors
|
||||
}
|
||||
this.cachedCharacteristics[serviceKey] = cachedCharacteristics
|
||||
}
|
||||
this.cachedServices[deviceKey] = cachedServices
|
||||
callback(Result.success(Unit))
|
||||
} else {
|
||||
val error = IllegalStateException("Discover GATT failed with status: $status")
|
||||
|
@ -483,12 +483,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> readCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey) async {
|
||||
Future<Uint8List> readCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -510,12 +510,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async {
|
||||
Future<void> writeCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey, Uint8List arg_value, int arg_myTypeNumber) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey, arg_value, arg_myTypeNumber]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -532,12 +532,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> notifyCharacteristic(int arg_myPeripheralKey, int arg_myCharacteristicKey, bool arg_state) async {
|
||||
Future<void> notifyCharacteristic(int arg_myPeripheralKey, int arg_myServiceKey, int arg_myCharacteristicKey, bool arg_state) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.notifyCharacteristic', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_state]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myServiceKey, arg_myCharacteristicKey, arg_state]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -554,12 +554,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List> readDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey) async {
|
||||
Future<Uint8List> readDescriptor(int arg_myPeripheralKey, int arg_myCharacteristicKey, int arg_myDescriptorKey) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.readDescriptor', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myDescriptorKey]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
@ -581,12 +581,12 @@ class MyCentralControllerHostApi {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> writeDescriptor(int arg_myPeripheralKey, int arg_myDescriptorKey, Uint8List arg_value) async {
|
||||
Future<void> writeDescriptor(int arg_myPeripheralKey, int arg_myCharacteristicKey, int arg_myDescriptorKey, Uint8List arg_value) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.writeDescriptor', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myDescriptorKey, arg_value]) as List<Object?>?;
|
||||
await channel.send(<Object?>[arg_myPeripheralKey, arg_myCharacteristicKey, arg_myDescriptorKey, arg_value]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
|
@ -126,18 +126,16 @@ class MyCentralController extends CentralController
|
||||
await _throwWithoutState(CentralState.poweredOn);
|
||||
final myPeripheral = peripheral as MyPeripheral;
|
||||
final myServiceArgses = await _myApi.getServices(myPeripheral.hashCode);
|
||||
return myServiceArgses
|
||||
.cast<MyGattServiceArgs>()
|
||||
.map(
|
||||
(myServiceArgs) => _myServices.putIfAbsent(
|
||||
myServiceArgs.key,
|
||||
() => MyGattService.fromMyArgs(
|
||||
myPeripheral,
|
||||
myServiceArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myServiceArgses.cast<MyGattServiceArgs>().map(
|
||||
(myServiceArgs) {
|
||||
final myService = MyGattService.fromMyArgs(
|
||||
myPeripheral,
|
||||
myServiceArgs,
|
||||
);
|
||||
_myServices[myService.hashCode] = myService;
|
||||
return myService;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -149,18 +147,16 @@ class MyCentralController extends CentralController
|
||||
final myCharactersiticArgses = await _myApi.getCharacteristics(
|
||||
myService.hashCode,
|
||||
);
|
||||
return myCharactersiticArgses
|
||||
.cast<MyGattCharacteristicArgs>()
|
||||
.map(
|
||||
(myCharacteristicArgs) => _myCharacteristics.putIfAbsent(
|
||||
myCharacteristicArgs.key,
|
||||
() => MyGattCharacteristic.fromMyArgs(
|
||||
myService,
|
||||
myCharacteristicArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myCharactersiticArgses.cast<MyGattCharacteristicArgs>().map(
|
||||
(myCharacteristicArgs) {
|
||||
final myCharacteristic = MyGattCharacteristic.fromMyArgs(
|
||||
myService,
|
||||
myCharacteristicArgs,
|
||||
);
|
||||
_myCharacteristics[myCharacteristic.hashCode] = myCharacteristic;
|
||||
return myCharacteristic;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -172,18 +168,16 @@ class MyCentralController extends CentralController
|
||||
final myDescriptorArgses = await _myApi.getDescriptors(
|
||||
myCharacteristic.hashCode,
|
||||
);
|
||||
return myDescriptorArgses
|
||||
.cast<MyGattDescriptorArgs>()
|
||||
.map(
|
||||
(myDescriptorArgs) => _myDescriptors.putIfAbsent(
|
||||
myDescriptorArgs.key,
|
||||
() => MyGattDescriptor.fromMyArgs(
|
||||
myCharacteristic,
|
||||
myDescriptorArgs,
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
return myDescriptorArgses.cast<MyGattDescriptorArgs>().map(
|
||||
(myDescriptorArgs) {
|
||||
final myDescriptor = MyGattDescriptor.fromMyArgs(
|
||||
myCharacteristic,
|
||||
myDescriptorArgs,
|
||||
);
|
||||
_myDescriptors[myDescriptor.hashCode] = myDescriptor;
|
||||
return myDescriptor;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -195,6 +189,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
final value = await _myApi.readCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
);
|
||||
return value;
|
||||
@ -214,6 +209,7 @@ class MyCentralController extends CentralController
|
||||
final typeNumber = typeArgs.index;
|
||||
await _myApi.writeCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
value,
|
||||
typeNumber,
|
||||
@ -231,6 +227,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
await _myApi.notifyCharacteristic(
|
||||
myPeripheral.hashCode,
|
||||
myService.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
state,
|
||||
);
|
||||
@ -245,6 +242,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
final value = await _myApi.readDescriptor(
|
||||
myPeripheral.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
myDescriptor.hashCode,
|
||||
);
|
||||
return value;
|
||||
@ -262,6 +260,7 @@ class MyCentralController extends CentralController
|
||||
final myPeripheral = myService.myPeripheral;
|
||||
await _myApi.writeDescriptor(
|
||||
myPeripheral.hashCode,
|
||||
myCharacteristic.hashCode,
|
||||
myDescriptor.hashCode,
|
||||
value,
|
||||
);
|
||||
@ -285,10 +284,8 @@ class MyCentralController extends CentralController
|
||||
int rssi,
|
||||
MyAdvertisementArgs myAdvertisementArgs,
|
||||
) {
|
||||
final myPeripheral = _myPeripherals.putIfAbsent(
|
||||
myPeripheralArgs.key,
|
||||
() => MyPeripheral.fromMyArgs(myPeripheralArgs),
|
||||
);
|
||||
final myPeripheral = MyPeripheral.fromMyArgs(myPeripheralArgs);
|
||||
_myPeripherals[myPeripheral.hashCode] = myPeripheral;
|
||||
final advertisement = myAdvertisementArgs.toAdvertisement();
|
||||
final eventArgs = CentralDiscoveredEventArgs(
|
||||
myPeripheral,
|
||||
|
@ -29,10 +29,15 @@ abstract class MyCentralControllerHostApi {
|
||||
List<MyGattCharacteristicArgs> getCharacteristics(int myServiceKey);
|
||||
List<MyGattDescriptorArgs> getDescriptors(int myCharacteristicKey);
|
||||
@async
|
||||
Uint8List readCharacteristic(int myPeripheralKey, int myCharacteristicKey);
|
||||
Uint8List readCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
);
|
||||
@async
|
||||
void writeCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
Uint8List value,
|
||||
int myTypeNumber,
|
||||
@ -40,14 +45,20 @@ abstract class MyCentralControllerHostApi {
|
||||
@async
|
||||
void notifyCharacteristic(
|
||||
int myPeripheralKey,
|
||||
int myServiceKey,
|
||||
int myCharacteristicKey,
|
||||
bool state,
|
||||
);
|
||||
@async
|
||||
Uint8List readDescriptor(int myPeripheralKey, int myDescriptorKey);
|
||||
Uint8List readDescriptor(
|
||||
int myPeripheralKey,
|
||||
int myCharacteristicKey,
|
||||
int myDescriptorKey,
|
||||
);
|
||||
@async
|
||||
void writeDescriptor(
|
||||
int myPeripheralKey,
|
||||
int myCharacteristicKey,
|
||||
int myDescriptorKey,
|
||||
Uint8List value,
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: bluetooth_low_energy_android
|
||||
description: Android implementation of the bluetooth_low_energy plugin.
|
||||
version: 2.0.0
|
||||
version: 2.0.1
|
||||
homepage: https://github.com/yanshouwang/bluetooth_low_energy
|
||||
|
||||
environment:
|
||||
@ -10,7 +10,7 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
bluetooth_low_energy_platform_interface: ^2.0.0
|
||||
bluetooth_low_energy_platform_interface: ^2.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Reference in New Issue
Block a user