Я пытаюсь реализовать приложение для передачи некоторых строк между устройствами (на данный момент одно устройство действует как центральное, а другое - как периферийное), но безуспешно.
Так настроено мое периферийное устройство (сервер). Характерная сборка
fun buildCharacteristic(
characteristicUUID: UUID,
): BluetoothGattCharacteristic {
var properties = BluetoothGattCharacteristic.PROPERTY_READ or
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or
BluetoothGattCharacteristic.PROPERTY_NOTIFY
var permission = BluetoothGattCharacteristic.PERMISSION_READ or
BluetoothGattCharacteristic.PERMISSION_WRITE
var characteristic = BluetoothGattCharacteristic(
characteristicUUID,
properties,
permission
)
return characteristic
}
сервисная сборка
fun buildService(
serviceUUID: UUID,
serviceType: Int,
characteristics: List<BluetoothGattCharacteristic>
) {
bluetoothGattService = BluetoothGattService(
serviceUUID,
BluetoothGattService.SERVICE_TYPE_PRIMARY
)
for (characteristic in characteristics) {
bluetoothGattService.addCharacteristic(characteristic)
}
}
и вот как я запускаю сервер (я опускаю реализацию обратных вызовов)
fun startServer(
bleAdapter: BluetoothAdapter,
btManager: BluetoothManager,
context: Context
) {
bleAdvertiser = bleAdapter.bluetoothLeAdvertiser
bleGattServer = btManager.openGattServer(context, gattServerCallback)
bleGattServer.addService(bluetoothGattService)
var settings = AdvertiseSettings.Builder().apply {
setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
setConnectable(true)
setTimeout(0)
setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
}
var data = AdvertiseData.Builder().apply {
setIncludeDeviceName(true)
}
bleAdvertiser.startAdvertising(settings.build(), data.build(), advertiseCallback)
}
На центральной (клиентской) стороне при срабатывании onScanResult я пытаюсь подключиться к устройству:
fun connectToDevice(device: BluetoothDevice) {
device.connectGatt(
context,
false,
createGattCallback()
)
}
где createGattCallback () - функция, возвращающая объект BluetoothGattCallback. Внутри этого обратного вызова, когда вызывается onConnectionStateChange, я вызываю обнаружение службы, а при обнаружении службы я пытаюсь записать данные на периферийное устройство.
override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
super.onServicesDiscovered(gatt, status)
if (gatt?.services != null) {
var serviceFound = false
for (service in gatt.services) {
if (service.uuid == Consts.SERVICE_UUID) {
serviceFound = true
var bluetoothGattCharacteristic = service.getCharacteristic(Consts.CHARACTERISTIC_UUID)
writeCharacteristic(
gatt,
bluetoothGattCharacteristic
)
}
}
if (!serviceFound) {
gatt.disconnect()
}
}
}
fun writeCharacteristic(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic
) {
var toSendString = "A random string for testing purpose only"
var toSendByteArray = toSendString.toByteArray(Charsets.UTF_8)
val chunkSize = 18
val numberOfPackets = ceil(
(toSendByteArray.size).toDouble() / chunkSize.toDouble()
)
for (i in 0 until numberOfPackets.toInt()) {
var startIndex = i * chunkSize
var endIndex = if (startIndex + chunkSize <= toSendByteArray.size) {
startIndex + chunkSize
} else {
toSendByteArray.size
}
var packet = toSendByteArray.copyOfRange(startIndex, endIndex)
characteristic.value = packet
gatt.writeCharacteristic(characteristic)
Thread.sleep(250)
}
}
Кажется, мой код не работает, на периферии я получаю не всю строку, а только первые 18 байтов. Где я не прав?