3.0.2 (#21)
* fix: 优化界面 * fix: 修复已知问题 * fix: 代码优化 * fix: 修复已知问题 * fix: 优化 getMaximumWriteLength 方法 * fix: 修改版本号 * fix: 修改版本号 * fix: 修改 CHANGELOG
This commit is contained in:
@ -351,9 +351,10 @@ interface MyCentralManagerHostApi {
|
||||
fun stopDiscovery()
|
||||
fun connect(peripheralHashCodeArgs: Long, callback: (Result<Unit>) -> Unit)
|
||||
fun disconnect(peripheralHashCodeArgs: Long, callback: (Result<Unit>) -> Unit)
|
||||
fun getMaximumWriteLength(peripheralHashCodeArgs: Long, callback: (Result<Long>) -> Unit)
|
||||
fun getMaximumWriteLength(peripheralHashCodeArgs: Long, typeNumberArgs: Long): Long
|
||||
fun readRSSI(peripheralHashCodeArgs: Long, callback: (Result<Long>) -> Unit)
|
||||
fun discoverGATT(peripheralHashCodeArgs: Long, callback: (Result<List<MyGattServiceArgs>>) -> Unit)
|
||||
fun requestMTU(peripheralHashCodeArgs: Long, mtuArgs: Long, callback: (Result<Long>) -> Unit)
|
||||
fun readCharacteristic(peripheralHashCodeArgs: Long, characteristicHashCodeArgs: Long, callback: (Result<ByteArray>) -> Unit)
|
||||
fun writeCharacteristic(peripheralHashCodeArgs: Long, characteristicHashCodeArgs: Long, valueArgs: ByteArray, typeNumberArgs: Long, callback: (Result<Unit>) -> Unit)
|
||||
fun notifyCharacteristic(peripheralHashCodeArgs: Long, characteristicHashCodeArgs: Long, stateArgs: Boolean, callback: (Result<Unit>) -> Unit)
|
||||
@ -464,15 +465,14 @@ interface MyCentralManagerHostApi {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val peripheralHashCodeArgsArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.getMaximumWriteLength(peripheralHashCodeArgsArg) { result: Result<Long> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
val typeNumberArgsArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
var wrapped: List<Any?>
|
||||
try {
|
||||
wrapped = listOf<Any?>(api.getMaximumWriteLength(peripheralHashCodeArgsArg, typeNumberArgsArg))
|
||||
} catch (exception: Throwable) {
|
||||
wrapped = wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
@ -518,6 +518,27 @@ interface MyCentralManagerHostApi {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralManagerHostApi.requestMTU", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val peripheralHashCodeArgsArg = args[0].let { if (it is Int) it.toLong() else it as Long }
|
||||
val mtuArgsArg = args[1].let { if (it is Int) it.toLong() else it as Long }
|
||||
api.requestMTU(peripheralHashCodeArgsArg, mtuArgsArg) { result: Result<Long> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralManagerHostApi.readCharacteristic", codec)
|
||||
if (api != null) {
|
||||
|
@ -15,6 +15,13 @@ class MyBluetoothGattServerCallback(private val peripheralManager: MyPeripheralM
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConnectionStateChange(device: BluetoothDevice, status: Int, newState: Int) {
|
||||
super.onConnectionStateChange(device, status, newState)
|
||||
executor.execute {
|
||||
peripheralManager.onConnectionStateChange(device, status, newState)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMtuChanged(device: BluetoothDevice, mtu: Int) {
|
||||
super.onMtuChanged(device, mtu)
|
||||
executor.execute {
|
||||
@ -36,6 +43,13 @@ class MyBluetoothGattServerCallback(private val peripheralManager: MyPeripheralM
|
||||
}
|
||||
}
|
||||
|
||||
override fun onExecuteWrite(device: BluetoothDevice, requestId: Int, execute: Boolean) {
|
||||
super.onExecuteWrite(device, requestId, execute)
|
||||
executor.execute {
|
||||
peripheralManager.onExecuteWrite(device, requestId, execute)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNotificationSent(device: BluetoothDevice, status: Int) {
|
||||
super.onNotificationSent(device, status)
|
||||
executor.execute {
|
||||
|
@ -29,6 +29,7 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
private val services = mutableMapOf<Long, BluetoothGattService>()
|
||||
private val characteristics = mutableMapOf<Long, BluetoothGattCharacteristic>()
|
||||
private val descriptors = mutableMapOf<Long, BluetoothGattDescriptor>()
|
||||
private val mtus = mutableMapOf<Long, Int>()
|
||||
|
||||
private val peripheralsArgs = mutableMapOf<Int, MyPeripheralArgs>()
|
||||
private val servicesArgsOfPeripherals = mutableMapOf<Long, List<MyGattServiceArgs>>()
|
||||
@ -43,7 +44,7 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
private var startDiscoveryCallback: ((Result<Unit>) -> Unit)? = null
|
||||
private val connectCallbacks = mutableMapOf<Long, (Result<Unit>) -> Unit>()
|
||||
private val disconnectCallbacks = mutableMapOf<Long, (Result<Unit>) -> Unit>()
|
||||
private val getMaximumWriteLengthCallbacks = mutableMapOf<Long, (Result<Long>) -> Unit>()
|
||||
private val requestMtuCallbacks = mutableMapOf<Long, (Result<Long>) -> Unit>()
|
||||
private val readRssiCallbacks = mutableMapOf<Long, (Result<Long>) -> Unit>()
|
||||
private val discoverGattCallbacks = mutableMapOf<Long, (Result<List<MyGattServiceArgs>>) -> Unit>()
|
||||
private val readCharacteristicCallbacks = mutableMapOf<Long, (Result<ByteArray>) -> Unit>()
|
||||
@ -89,6 +90,7 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
services.clear()
|
||||
characteristics.clear()
|
||||
descriptors.clear()
|
||||
mtus.clear()
|
||||
peripheralsArgs.clear()
|
||||
servicesArgsOfPeripherals.clear()
|
||||
servicesArgs.clear()
|
||||
@ -98,7 +100,7 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
startDiscoveryCallback = null
|
||||
connectCallbacks.clear()
|
||||
disconnectCallbacks.clear()
|
||||
getMaximumWriteLengthCallbacks.clear()
|
||||
requestMtuCallbacks.clear()
|
||||
readRssiCallbacks.clear()
|
||||
discoverGattCallbacks.clear()
|
||||
readCharacteristicCallbacks.clear()
|
||||
@ -172,23 +174,33 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMaximumWriteLength(peripheralHashCodeArgs: Long, callback: (Result<Long>) -> Unit) {
|
||||
override fun requestMTU(peripheralHashCodeArgs: Long, mtuArgs: Long, callback: (Result<Long>) -> Unit) {
|
||||
try {
|
||||
val unfinishedCallback = getMaximumWriteLengthCallbacks[peripheralHashCodeArgs]
|
||||
val unfinishedCallback = requestMtuCallbacks[peripheralHashCodeArgs]
|
||||
if (unfinishedCallback != null) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
val gatt = bluetoothGATTs[peripheralHashCodeArgs] as BluetoothGatt
|
||||
val requesting = gatt.requestMtu(517)
|
||||
val mtu = mtuArgs.toInt()
|
||||
val requesting = gatt.requestMtu(mtu)
|
||||
if (!requesting) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
getMaximumWriteLengthCallbacks[peripheralHashCodeArgs] = callback
|
||||
requestMtuCallbacks[peripheralHashCodeArgs] = callback
|
||||
} catch (e: Throwable) {
|
||||
callback(Result.failure(e))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMaximumWriteLength(peripheralHashCodeArgs: Long, typeNumberArgs: Long): Long {
|
||||
val mtu = mtus[peripheralHashCodeArgs] ?: 23
|
||||
val maximumWriteLength = when (typeNumberArgs.toWriteTypeArgs()) {
|
||||
MyGattCharacteristicWriteTypeArgs.WITHRESPONSE -> 512
|
||||
MyGattCharacteristicWriteTypeArgs.WITHOUTRESPONSE -> (mtu - 3).coerceIn(20, 512)
|
||||
}
|
||||
return maximumWriteLength.toLong()
|
||||
}
|
||||
|
||||
override fun readRSSI(peripheralHashCodeArgs: Long, callback: (Result<Long>) -> Unit) {
|
||||
try {
|
||||
val unfinishedCallback = readRssiCallbacks[peripheralHashCodeArgs]
|
||||
@ -414,14 +426,15 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
val deviceHashCode = device.hashCode()
|
||||
val peripheralArgs = peripheralsArgs[deviceHashCode] as MyPeripheralArgs
|
||||
val peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
|
||||
// Check callbacks
|
||||
if (newState != BluetoothProfile.STATE_CONNECTED) {
|
||||
// check connection state.
|
||||
if (newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
gatt.close()
|
||||
bluetoothGATTs.remove(peripheralHashCodeArgs)
|
||||
mtus.remove(peripheralHashCodeArgs)
|
||||
val error = IllegalStateException("GATT is disconnected with status: $status")
|
||||
val getMaximumWriteLengthCallback = getMaximumWriteLengthCallbacks.remove(peripheralHashCodeArgs)
|
||||
if (getMaximumWriteLengthCallback != null) {
|
||||
getMaximumWriteLengthCallback(Result.failure(error))
|
||||
val requestMtuCallback = requestMtuCallbacks.remove(peripheralHashCodeArgs)
|
||||
if (requestMtuCallback != null) {
|
||||
requestMtuCallback(Result.failure(error))
|
||||
}
|
||||
val readRssiCallback = readRssiCallbacks.remove(peripheralHashCodeArgs)
|
||||
if (readRssiCallback != null) {
|
||||
@ -470,35 +483,25 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check state
|
||||
val stateArgs = newState == BluetoothProfile.STATE_CONNECTED
|
||||
api.onPeripheralStateChanged(peripheralArgs, stateArgs) {}
|
||||
// check connect & disconnect callbacks.
|
||||
val connectCallback = connectCallbacks.remove(peripheralHashCodeArgs)
|
||||
val disconnectCallback = disconnectCallbacks.remove(peripheralHashCodeArgs)
|
||||
if (connectCallback == null && disconnectCallback == null) {
|
||||
// State changed.
|
||||
val stateArgs = newState == BluetoothProfile.STATE_CONNECTED
|
||||
api.onPeripheralStateChanged(peripheralArgs, stateArgs) {}
|
||||
} else {
|
||||
if (connectCallback != null) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
// Connect succeed.
|
||||
connectCallback(Result.success(Unit))
|
||||
api.onPeripheralStateChanged(peripheralArgs, true) {}
|
||||
} else {
|
||||
// Connect failed.
|
||||
val error = IllegalStateException("Connect failed with status: $status")
|
||||
connectCallback(Result.failure(error))
|
||||
}
|
||||
if (connectCallback != null) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
connectCallback(Result.success(Unit))
|
||||
} else {
|
||||
val error = IllegalStateException("Connect failed with status: $status")
|
||||
connectCallback(Result.failure(error))
|
||||
}
|
||||
if (disconnectCallback != null) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
// Disconnect succeed.
|
||||
disconnectCallback(Result.success(Unit))
|
||||
api.onPeripheralStateChanged(peripheralArgs, false) {}
|
||||
} else {
|
||||
// Disconnect failed.
|
||||
val error = IllegalStateException("Connect failed with status: $status")
|
||||
disconnectCallback(Result.failure(error))
|
||||
}
|
||||
}
|
||||
if (disconnectCallback != null) {
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
disconnectCallback(Result.success(Unit))
|
||||
} else {
|
||||
val error = IllegalStateException("Disconnect failed with status: $status")
|
||||
disconnectCallback(Result.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -508,12 +511,15 @@ class MyCentralManager(private val context: Context, binaryMessenger: BinaryMess
|
||||
val hashCode = device.hashCode()
|
||||
val peripheralArgs = peripheralsArgs[hashCode] as MyPeripheralArgs
|
||||
val peripheralHashCodeArgs = peripheralArgs.hashCodeArgs
|
||||
val callback = getMaximumWriteLengthCallbacks.remove(peripheralHashCodeArgs) ?: return
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
val maximumWriteLengthArgs = (mtu - 3).toLong()
|
||||
callback(Result.success(maximumWriteLengthArgs))
|
||||
mtus[peripheralHashCodeArgs] = mtu
|
||||
}
|
||||
val callback = requestMtuCallbacks.remove(peripheralHashCodeArgs) ?: return
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
val mtuArgs = mtu.toLong()
|
||||
callback(Result.success(mtuArgs))
|
||||
} else {
|
||||
val error = IllegalStateException("Get maximum write length failed with status: $status")
|
||||
val error = IllegalStateException("Request MTU failed with status: $status")
|
||||
callback(Result.failure(error))
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
private val descriptors = mutableMapOf<Long, BluetoothGattDescriptor>()
|
||||
private val mtus = mutableMapOf<Long, Int>()
|
||||
private val confirms = mutableMapOf<Long, Boolean>()
|
||||
private val preparedCharacteristics = mutableMapOf<Int, BluetoothGattCharacteristic>()
|
||||
private val preparedValues = mutableMapOf<Int, ByteArray>()
|
||||
private val values = mutableMapOf<Long, ByteArray>()
|
||||
|
||||
private val centralsArgs = mutableMapOf<Int, MyCentralArgs>()
|
||||
private val servicesArgs = mutableMapOf<Int, MyGattServiceArgs>()
|
||||
@ -81,6 +84,9 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
descriptors.clear()
|
||||
mtus.clear()
|
||||
confirms.clear()
|
||||
preparedCharacteristics.clear()
|
||||
preparedValues.clear()
|
||||
values.clear()
|
||||
centralsArgs.clear()
|
||||
servicesArgs.clear()
|
||||
characteristicsArgs.clear()
|
||||
@ -218,7 +224,8 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
|
||||
override fun getMaximumWriteLength(centralHashCodeArgs: Long): Long {
|
||||
val mtu = mtus[centralHashCodeArgs] ?: 23
|
||||
return (mtu - 3).toLong()
|
||||
val maximumWriteLength = (mtu - 3).coerceIn(20, 512)
|
||||
return maximumWriteLength.toLong()
|
||||
}
|
||||
|
||||
override fun sendReadCharacteristicReply(centralHashCodeArgs: Long, characteristicHashCodeArgs: Long, idArgs: Long, offsetArgs: Long, statusArgs: Boolean, valueArgs: ByteArray) {
|
||||
@ -239,7 +246,7 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
val status = if (statusArgs) BluetoothGatt.GATT_SUCCESS
|
||||
else BluetoothGatt.GATT_FAILURE
|
||||
val offset = offsetArgs.toInt()
|
||||
val value = null
|
||||
val value = values.remove(idArgs) as ByteArray
|
||||
val sent = server.sendResponse(device, requestId, status, offset, value)
|
||||
if (!sent) {
|
||||
throw IllegalStateException("Send write characteristic reply failed.")
|
||||
@ -335,6 +342,13 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
callback(Result.failure(error))
|
||||
}
|
||||
|
||||
fun onConnectionStateChange(device: BluetoothDevice, status: Int, newState: Int) {
|
||||
val hashCode = device.hashCode()
|
||||
val centralArgs = centralsArgs.getOrPut(hashCode) { device.toCentralArgs() }
|
||||
val centralHashCodeArgs = centralArgs.hashCodeArgs
|
||||
devices[centralHashCodeArgs] = device
|
||||
}
|
||||
|
||||
fun onMtuChanged(device: BluetoothDevice, mtu: Int) {
|
||||
val hashCode = device.hashCode()
|
||||
val centralArgs = centralsArgs.getOrPut(hashCode) { device.toCentralArgs() }
|
||||
@ -360,11 +374,49 @@ class MyPeripheralManager(private val context: Context, binaryMessenger: BinaryM
|
||||
val centralArgs = centralsArgs.getOrPut(deviceHashCode) { device.toCentralArgs() }
|
||||
val centralHashCodeArgs = centralArgs.hashCodeArgs
|
||||
devices[centralHashCodeArgs] = device
|
||||
if (preparedWrite) {
|
||||
val preparedCharacteristic = preparedCharacteristics[deviceHashCode]
|
||||
if (preparedCharacteristic != null && preparedCharacteristic != characteristic) {
|
||||
val status = BluetoothGatt.GATT_CONNECTION_CONGESTED
|
||||
server.sendResponse(device, requestId, status, offset, value)
|
||||
return
|
||||
}
|
||||
val preparedValue = preparedValues[deviceHashCode]
|
||||
if (preparedValue == null) {
|
||||
preparedCharacteristics[deviceHashCode] = characteristic
|
||||
preparedValues[deviceHashCode] = value
|
||||
} else {
|
||||
preparedValues[deviceHashCode] = preparedValue.plus(value)
|
||||
}
|
||||
val status = BluetoothGatt.GATT_SUCCESS
|
||||
server.sendResponse(device, requestId, status, offset, value)
|
||||
} else {
|
||||
val characteristicHashCode = characteristic.hashCode()
|
||||
val characteristicArgs = characteristicsArgs[characteristicHashCode] as MyGattCharacteristicArgs
|
||||
val idArgs = requestId.toLong()
|
||||
val offsetArgs = offset.toLong()
|
||||
values[idArgs] = value
|
||||
api.onWriteCharacteristicCommandReceived(centralArgs, characteristicArgs, idArgs, offsetArgs, value) {}
|
||||
}
|
||||
}
|
||||
|
||||
fun onExecuteWrite(device: BluetoothDevice, requestId: Int, execute: Boolean) {
|
||||
val deviceHashCode = device.hashCode()
|
||||
val centralArgs = centralsArgs[deviceHashCode] as MyCentralArgs
|
||||
val characteristic = preparedCharacteristics.remove(deviceHashCode) as BluetoothGattCharacteristic
|
||||
val characteristicHashCode = characteristic.hashCode()
|
||||
val characteristicArgs = characteristicsArgs[characteristicHashCode] as MyGattCharacteristicArgs
|
||||
val idArgs = requestId.toLong()
|
||||
val offsetArgs = offset.toLong()
|
||||
api.onWriteCharacteristicCommandReceived(centralArgs, characteristicArgs, idArgs, offsetArgs, value) {}
|
||||
val value = preparedValues.remove(deviceHashCode) as ByteArray
|
||||
if (execute) {
|
||||
val idArgs = requestId.toLong()
|
||||
val offsetArgs = 0L
|
||||
values[idArgs] = value
|
||||
api.onWriteCharacteristicCommandReceived(centralArgs, characteristicArgs, idArgs, offsetArgs, value) {}
|
||||
} else {
|
||||
val status = BluetoothGatt.GATT_SUCCESS
|
||||
val offset = 0
|
||||
server.sendResponse(device, requestId, status, offset, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun onDescriptorReadRequest(device: BluetoothDevice, requestId: Int, offset: Int, descriptor: BluetoothGattDescriptor) {
|
||||
|
Reference in New Issue
Block a user