蓝牙 - BLE数据超过23字节(MTU),notify长度

现象

ble设备发送数据帧超过20字节后,手机无法接收到数据。

原因

在低功耗蓝牙连接中,属性协议默认的MTU长度为23字节。按照1个字节的类型操作码(六种基本操作:请求、响应、命令、指示、确认、通知)以及最少2个字节操作句柄(16BitsUUID)算,数据传输字节最多不超过20字节。在两个设备连接初期,谁也不知道对方底细,因此数据交换严格按照默认MTU来,即MTU为23字节

如果设备想要发送更大的数据包,那么它就要协商一个更长的MTU。只有客户端可以发起这种请求。客户端的请求包含客户端接收的MTU长度;服务器请求则包含服务器接受的MTU长度。对于同时是是客户端服务器的设备而言,二者提供的接收MTU长度中较小的那个即是连接将会使用的MTU长度。

解决

  • 设备端修改MTU长度
  • 手机端修改MTU长度
    在这里插入图片描述
    在这里插入图片描述
### Android 平台上的蓝牙低功耗 (BLE) 数据传输 在 Android 上实现 BLE 数据传输涉及多个方面的工作,包括初始化、扫描设备、建立连接以及实际的数据交换过程。 #### 初始化与权限设置 为了能够访问蓝牙功能,在 `AndroidManifest.xml` 文件中需声明必要的权限: ```xml <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <!-- For API level >= 23 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> ``` 对于 Android 6.0 及以上版本还需要动态请求位置信息权限[^1]。 #### 扫描并连接至目标设备 当应用程序启动时,可以调用 BluetoothAdapter 的 startLeScan 方法来查找附近的 BLE 设备。一旦找到所需的目标设备,则通过该设备对象创建一个 GATT 客户端实例来进行进一步操作: ```java private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED){ Log.i(TAG,"Connected to GATT server."); // 发现服务... gatt.discoverServices(); } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if(status==BluetoothGatt.GATT_SUCCESS){ // 获取特定的服务和服务中的特征值用于读写数据 } } }; // 连接到指定的远程设备 bluetoothGatt = device.connectGatt(context,false,gattCallback); ``` 上述代码片段展示了如何定义回调函数处理连接状态变化,并尝试发现可用的服务[^3]。 #### 数据交互流程 完成连接之后就可以准备发送或接收来自外围设备的信息了。这通常涉及到以下几个步骤: - **获取 Characteristic**: 查找感兴趣的特性(Characteristic),这些特性代表了可被读取或写的属性。 - **订阅通知/指示**: 如果希望实时监听某些特性的更新情况,可以通过 enableNotification 或者 enableIndication 来开启相应的机制。 - **执行读写操作**: 利用 readCharacteristic/writeCharacteristic 函数可以直接作用于选定的对象上。 下面是一个简单的例子说明怎样向服务器写入数据: ```java public boolean writeCustomCharacteristic(byte[] value){ BluetoothGattService service = bluetoothGatt.getService(UUID.fromString("YOUR_SERVICE_UUID")); if(service!=null){ BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("YOUR_CHARACTERISTIC_UUID")); if(characteristic != null && characteristic.setValue(value)){ return bluetoothGatt.writeCharacteristic(characteristic); } } return false; } ``` 此方法接受字节数组作为参数传递给远端设备的一个自定义特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值