Android BLE中传输数据的最大长度怎么破

本文探讨了Android GATT在传输数据时遇到的20字节限制问题,原因在于默认MTU为23字节,实际留给GATT的只有20字节。通过调整ATT MTU可以突破限制,Android API 21提供了设置MTU的接口。优雅实现的方法包括采用二分法协商合适的MTU值,确保设备兼容性和效率。
摘要由CSDN通过智能技术生成

 好多小伙伴们都被一个事儿困扰过:

想在gatt client上(一般是手机上)传输长一点的数据给gatt server(一般是一个Bluetooth smart设备,即只有BLE功能的设备),但通过

 writeCharacteristic(BluetoothGattCharacteristic)
来写的时候发现最多只能写入20个byte的数据。

这篇文章会回答下面几个问题:

1)为什么会是20?

2)如何突破20?

3)如何更优雅的来实现?


第一个问题,为什么为限制成20个字节?

core spec里面定义了ATT的默认MTU为23个bytes,除去ATT的opcode一个字节以及ATT的handle2个字节之后,剩下的20个字节便是留给GATT的了。


考虑到有些Bluetooth smart设备功能弱小,不敢太奢侈的使用内存空间,因此core spec规定每一个设备都必须支持MTU为23。

在两个设备连接初期,大家都像新交的朋友一样,不知对方底细,因此严格的按照套路来走,即最多一次发20个字节,是最保险的。


由于ATT的最大长度为512byte,


因此一般认为MTU的最大长度为512个byte就够了,再大也没什么意义,你不可能发一个超过512的ATT的数据,就像是孙猴

Android BLE开发,如果接收到的数据包大小超过了默认的最大MTU最大传输单元)大小,那么需要将数据分成多个小包发送,这就需要在接收方进行分包处理。下面是一个简单的示例代码,用于接收分包数据: ```java private byte[] mReceivedData; private void onCharacteristicChanged(BluetoothGattCharacteristic characteristic) { byte[] data = characteristic.getValue(); int offset = 0; while (offset < data.length) { // 获取数据包的header,即前4个字节,用于判断是否是完整的数据包 byte[] header = Arrays.copyOfRange(data, offset, offset + 4); int packetLength = ByteBuffer.wrap(header).order(ByteOrder.LITTLE_ENDIAN).getInt(); // 如果当前数据包不完整,等待下一个包到达 if (offset + packetLength > data.length) { break; } // 将完整的数据包存储到mReceivedData byte[] packet = Arrays.copyOfRange(data, offset + 4, offset + packetLength); mReceivedData = ArrayUtils.addAll(mReceivedData, packet); // 继续处理下一个数据包 offset += packetLength; } // 如果mReceivedData有完整的数据包,则进行处理 if (isCompletePacketReceived()) { handleReceivedPacket(mReceivedData); mReceivedData = null; } } private boolean isCompletePacketReceived() { if (mReceivedData == null) { return false; } int packetLength = ByteBuffer.wrap(mReceivedData).order(ByteOrder.LITTLE_ENDIAN).getInt(); return mReceivedData.length == packetLength + 4; } private void handleReceivedPacket(byte[] data) { // 处理完整的数据包 } ``` 以上代码,假设接收到的分包数据是由一个4字节的header和一个数据包组成。header用于表示整个数据包的长度数据不包含header。在onCharacteristicChanged()回调,我们首先将所有接收到的数据存储到一个byte数组(mReceivedData),然后根据header判断每个数据包是否完整,如果当前数据包不完整,则等待下一个包到达。如果当前数据包完整,就将其存储到mReceivedData。最后,如果mReceivedData有完整的数据包,则处理该数据包。 需要注意的是,以上代码仅作为示例,实际应用需要根据数据包的具体格式进行相应的修改。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值