【发布时间】:2015-07-17 07:16:20
【问题描述】:
这是我在 SO 上的第一篇文章。
我在 android 5.0.2 上订阅 GATT 通知时遇到一些问题。
我的目标是将带有 BLE Shield 的 Arduino 连接到我的 Android 手机。我有一个连接到 Arduino 的传感器,并希望使用 BLE 屏蔽将数据从 Arduino 发送到我的手机。 盾上有一个nRF8001是服务器,我的手机/应用程序是客户端。
我所做的到目前为止是创建一个扫描 BLE 设备的 Android 应用程序。它可以连接到设备并读取或写入特征。所以,我可以通过调用gatt.readCharacteristic(mCharacteristic);“手动”读取特征。这使我可以从 Arduino 获取传感器值。
我还使用 nRFGo Studio 创建了一个自定义服务。我知道这部分正在工作,因为我能够通过使用 Google Play 上提供的 BLE Scanner 应用程序来发现、连接甚至收到有关特性更改的通知。
但是在我自己的应用程序中订阅通知是行不通的。好吧,至少订阅有效,但永远不会调用 onCharacteristicChanged(...)。有趣的是,如果我在我的应用程序中订阅了该特性,然后之后 使用 BLE 扫描仪应用程序订阅它,就会突然调用onCharacteristicChanged(...),直到我再次通过 BLE 扫描仪应用程序取消订阅。 (我可以通过日志看到这一点)
我的安卓代码如下: 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) {
}
};
这是我连接到 GATT 的方式:
bt_device = createBluetoothDevice(DEVICE_ADRESS);
BluetoothGatt mBluetoothGatt = bt_device.connectGatt(context, false, mGattCallback);
所有这些代码都在后台服务中运行,该服务在选择 BLE 设备后启动。
我尝试过的是实现 Google Dev API 指南中演示的内容,我还尝试了 this solution(没有成功)。在 Google 上搜索、阅读 SO 上已经提出的问题(例如 this one )或查看北欧开发者专区在这种情况下都没有多大帮助。
最后,我的问题是:我做错了什么?我错过了什么吗? 我只是想不通,这让我发疯了两天。我不知道我还能在哪里寻找解决方案,所以我希望你能帮助我..
编辑全局类:
// 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");
编辑我在 BLE 扫描仪中的工作: 我只是扫描 BLE 设备。它找到了我的设备,点击它后,它会显示我在 Arduino 板上设置的所有服务。选择服务后,它会显示我为该服务指定的所有特性。当我点击一个特性时,它会显示它的 UUID 和它的服务的 UUID。此外,BLE Scanner 应用程序允许我订阅通知或读取特征。当我订阅时,值会不断更新。
【问题讨论】:
-
你能发布你的
Globals吗? -
另外,您能否发布您在 BLE 扫描仪中所做的工作以使其正常工作?
-
是的,我主要想知道您是否确定您的 UUID 与您在 BLE 扫描仪中选择的匹配。
-
感谢您的链接,但我已经找到了这个:因为我没有多个特征,所以我没有创建队列。目前,我没有修改或编写任何特征,但这样做是为了测试目的。不过,当我测试阅读时,我确保之前调用了
onDescriptorWrite()。重新启动我的设备也没有帮助。描述符的写法与第一个答案中的相似。我还重新检查了 UUID,但它们都与 BLE 扫描仪中的 UUID 和我在 nRFGo Studio 中设置的一致。
标签: android arduino bluetooth-lowenergy gatt