ord*_*sen 9 android arduino bluetooth-lowenergy gatt
这是我关于SO的第一篇文章.
我在Android 5.0.2上订阅GATT通知时遇到了一些问题.
我的目的是将Arduino和BLE Shield连接到我的Android手机.我有一个连接到Arduino的传感器,想要使用BLE屏蔽将数据从Arduino发送到我的手机.盾牌上有一个nRF8001是服务器,我的手机/应用程序是客户端.
到目前为止我所做的是创建一个扫描BLE设备的Android应用程序.它可以连接到设备并读取或写入特征.所以,我可以通过调用"手动"读取特征gatt.readCharacteristic(mCharacteristic);.这允许我从Arduino获取传感器值.我还使用nRFGo Studio创建了一个自定义服务.我知道这部分工作正常,因为我可以使用Google Play上提供的BLE扫描仪应用程序发现,连接甚至收到有关特征变化的通知.但订阅我自己的应用程序中的通知将无法正常工作.好吧,至少订阅有效,但onCharacteristicChanged(...)从未调用过.有趣的是,如果我订阅我的应用程序中的特性,然后使用BLE扫描仪应用程序订阅它突然onCharacteristicChanged(...)被调用,直到我再次通过BLE扫描仪应用程序取消订阅.(我可以通过Log看到这个)
我的android代码如下:GATT回调:
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
sendBroadcastConnected();
Log.i("BLE", "Connected to GATT server.");
Log.i("BLE", "Attempting to start service discovery:" + bleManager.startServiceDiscovery());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
sendBroadcastDisconnected();
Log.i("BLE", "Disconnected from GATT server.");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.w("BLE", "onServicesDiscovered ");
setNotifySensor(gatt);
}
}
private void setNotifySensor(BluetoothGatt gatt) {
BluetoothGattCharacteristic characteristic = gatt.getService(Globals.MPU_SERVICE_UUID).getCharacteristic(Globals.X_ACCEL_CHARACTERISTICS_UUID);
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor desc = characteristic.getDescriptor(Globals.X_ACCEL_DESCRIPTOR_UUID);
Log.i("BLE", "Descriptor is " + desc); // this is not null
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
Log.i("BLE", "Descriptor write: " + gatt.writeDescriptor(desc)); // returns true
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if(Globals.X_ACCEL_CHARACTERISTICS_UUID.equals(characteristic.getUuid())){
Log.w("BLE", "CharacteristicRead - xaccel service uuid: " + characteristic.getService().getUuid());
Log.w("BLE", "CharacteristicRead - xaccel value: " + characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8,0));
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i("BLE", "Received characteristics changed event : "+characteristic.getUuid());
if(Globals.X_ACCEL_CHARACTERISTICS_UUID.equals(characteristic.getUuid())){
Log.i("BLE", "Received new value for xAccel.");
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
}
};
Run Code Online (Sandbox Code Playgroud)
这就是我连接GATT的方式:
bt_device = createBluetoothDevice(DEVICE_ADRESS);
BluetoothGatt mBluetoothGatt = bt_device.connectGatt(context, false, mGattCallback);
Run Code Online (Sandbox Code Playgroud)
所有这些代码都在后台服务中运行,后台服务在选择BLE设备后启动.
我尝试的是实现Google Dev API指南中演示的内容,我也试过这个解决方案(没有成功).既没有在谷歌上搜索,也没有在SO(例如这个)上阅读问题或者看过北欧开发者专区,这在这种情况下确实有很大帮助.
最后,我的问题是:我做错了什么?我错过了什么吗?我只是无法理解它现在让我疯狂了两天.我不知道我还能在哪里寻找解决方案,所以我希望你能帮助我..
编辑全球类:
// BLE Services
public static final UUID MPU_SERVICE_UUID = UUID.fromString("3f540001-1ee0-4245-a7ef-35885ccae141");
// BLE Characteristics
public static final UUID X_ACCEL_CHARACTERISTICS_UUID = UUID.fromString("3f540002-1ee0-4245-a7ef-35885ccae141");
// BLE Descriptors
public static final UUID X_ACCEL_DESCRIPTOR_UUID = UUID.fromString("3f542902-1ee0-4245-a7ef-35885ccae141");
Run Code Online (Sandbox Code Playgroud)
编辑我在BLE扫描仪中做的事情: 我只是扫描BLE设备.它找到了我的设备并在点击它之后向我展示了我在Arduino板上设置的所有服务.选择服务后,它会显示我为此服务指定的所有聊天功能.当我点击一个特征时,它会显示它的UUID及其服务的UUID.此外,BLE扫描仪应用程序允许我订阅通知或阅读特征.订阅时,该值会不断更新.
所以,我最终弄清楚了我的错误:)正如你在上面看到的那样,我使用的UUID具有与我的描述符相同的基础作为我的特征(从开始3f54XXXX-....)
我把它改成了public static final UUID X_ACCEL_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");,现在一切都按预期工作了.
之前我没有这样做,因为我认为应该有每个特征的描述符.但实际上,根据客户端特性配置 ...
[...]描述符应在绑定设备的连接上保持不变.客户端特征配置描述符对于每个客户端是唯一的.
所以我查看了RedBearLab Android App示例,发现描述符的UUID等于其他SO答案上发布的UUID.
这也解释了为什么我的应用程序在BLE扫描仪应用程序中启用后会收到通知:由于描述符应在绑定设备的连接上保持不变,因此BLE扫描程序应用程序也使用此UUID作为描述符,从而为客户端启用通知(=我的手机).
| 归档时间: |
|
| 查看次数: |
12315 次 |
| 最近记录: |