OnServicesDiscovery中的Android BluetoothGatt.getServices(xyz)为onScanResult ScanRecord.getServiceUuids()中列出的服务xyz返回null
自2013/API18/4.3以来,我一直在Android上做BLE。OnServicesDiscovery中的Android BluetoothGatt.getServices(xyz)为onScanResult ScanRecord.getServiceUuids()中列出的服务xyz返回null,android,bluetooth,bluetooth-lowenergy,android-bluetooth,android-ble,Android,Bluetooth,Bluetooth Lowenergy,Android Bluetooth,Android Ble,自2013/API18/4.3以来,我一直在Android上做BLE。 我知道我在做什么,但我不能解决这个简单的问题 我正在成功扫描可扩展设备,并在ScanCallback.onScanResult(…)中记录ScanRecord.getServiceUuids()(此处所示为制造商特定数据上的列索引标题): 此扫描日志记录是一致的,并可靠地显示扫描设备0E:0E:00:00:57具有ServiceUUID=[0000fa25-0000-1000-8000-00805f9b34fb] 扫描设备0
我知道我在做什么,但我不能解决这个简单的问题 我正在成功扫描可扩展设备,并在ScanCallback.onScanResult(…)中记录ScanRecord.getServiceUuids()(此处所示为制造商特定数据上的列索引标题):
此扫描日志记录是一致的,并可靠地显示扫描设备0E:0E:00:00:57具有ServiceUUID=[0000fa25-0000-1000-8000-00805f9b34fb]
扫描设备0E:0E:00:00:00:57后不久,我使用BluetoothGatt连接到它,并将特征写入0000fa25-0000-1000-8000-00805f9b34fb服务。
这是我的Gathandler课程的完整日志(我很快就会开源): 。。。在OnServicesDiscovery中,我调用gatt.getServices()并将其报告给侦听器MyBleDevice,该侦听器记录所有服务
01-19 18:04:58.127 10363-10363/com.foo V/MyBleDevice: T10363 0E:0E:00:00:00:57 onServiceDiscovered(service="Generic Attribute Service"(0x1801))
请注意,在连接的设备上只报告发现一个服务这就是在扫描时报告其服务0000fa25-0000-1000-8000-00805f9b34fb的同一台设备
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 pendingOperationWait: operation=Connect, elapsedMillis=1004
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 pendingOperationWait: operation=Connect, elapsedMillis=1004; SIGNALED/COMPLETED
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 -connect.run(): autoConnect=false, timeoutMillis=10000
01-19 18:05:05.940 10363-10363/com.foo I/GattHandler: T10363 0E:0E:00:00:00:57 characteristicWrite(serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000)
01-19 18:05:05.943 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 +characteristicWrite.run(): serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000
01-19 18:05:05.944 10363-10451/com.foo E/GattHandler: T10451 0E:0E:00:00:00:57 characteristicWrite: gatt.getService(0000fa25-0000-1000-8000-00805f9b34fb) returned null; failing
01-19 18:05:05.964 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 -characteristicWrite.run(): serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000
请注意“getService(…)返回null;失败”
这是在Pixel XL上运行的最新版本,自发布之日起,Android 7.1。BLE设备是一种自定义设备,可在非Android BLE设备上正常工作。
请注意,这在大多数情况下都有效,但不足以轻松装运产品 有什么想法吗? 这是我的Gathandler的代码。characteristicWrite(…):
“0000fa25-0000-1000-8000-00805f9b34fb”甚至不是蓝牙SIG注册的有效UUID。你正在连接什么外围设备?请注意,仅仅因为它在为一项服务做广告并不意味着它实际上在GATT数据库中有它(即使这违反了规范)。它是我工作的公司制造的定制设备。该设备确实有这项服务,而且大部分时间都可以使用,但没有足够的时间轻松地将产品交付给公众。我不相信“getService(…)”调用本身实际上与设备本身进行通信,因此我相信设备上的Android[缓存?]信息有问题,而不是设备本身。如果您要发布该产品,您需要将UUID更改为超出Bluetooth SIG保留的范围。无论如何,您可以查看Wireshark中的Bluetooth HCI snoop日志,了解服务发现过程失败的原因。您还应该尝试将其连接到另一个GATT实现,例如iOS设备,并查看那里发生了什么。使用合适的应用程序,如LightBlue或nRF Connect来调试服务列表(在iOS和Android上)。我不确定我是否理解您的OnServicesDiscovery(这里有些东西)代码行。我的理解是,它看起来像是在服务上发现的这种公共空白(BluetoothGatt,int status),是调用gatt.discoverServices()的结果。调用之后,我将获得所有服务,而不仅仅是所有外围设备必须支持的标准必需服务。在OnServicesDiscovery中,我只需调用gatt.getServices()并将结果数组/列表中的每个服务回调到单独的侦听器。在这种情况下,我的设备上只列出一个服务0x1801。但广告上说它有0000fa25-0000-1000-8000-00805f9b34fb。稍后我尝试写入服务0000fa25-0000-1000-8000-00805f9b34fb,getService返回null。
01-19 18:04:58.127 10363-10363/com.foo V/MyBleDevice: T10363 0E:0E:00:00:00:57 onServiceDiscovered(service="Generic Attribute Service"(0x1801))
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 pendingOperationWait: operation=Connect, elapsedMillis=1004
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 pendingOperationWait: operation=Connect, elapsedMillis=1004; SIGNALED/COMPLETED
01-19 18:04:58.124 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 -connect.run(): autoConnect=false, timeoutMillis=10000
01-19 18:05:05.940 10363-10363/com.foo I/GattHandler: T10363 0E:0E:00:00:00:57 characteristicWrite(serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000)
01-19 18:05:05.943 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 +characteristicWrite.run(): serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000
01-19 18:05:05.944 10363-10451/com.foo E/GattHandler: T10451 0E:0E:00:00:00:57 characteristicWrite: gatt.getService(0000fa25-0000-1000-8000-00805f9b34fb) returned null; failing
01-19 18:05:05.964 10363-10451/com.foo V/GattHandler: T10451 0E:0E:00:00:00:57 -characteristicWrite.run(): serviceUuid=0000fa25-0000-1000-8000-00805f9b34fb, characteristicUuid=00002c02-0000-1000-8000-00805f9b34fb, value=[1], characteristicWriteType=DefaultWithResponse, timeoutMillis=10000
public void characteristicWrite(final UUID serviceUuid, final UUID characteristicUuid,
final byte[] value,
final CharacteristicWriteType characteristicWriteType,
final long timeoutMillis)
{
Log.i(TAG, mDeviceAddressString +
" characteristicWrite(serviceUuid=" + serviceUuid +
", characteristicUuid=" + characteristicUuid +
", value=" + Arrays.toString(value) +
", characteristicWriteType=" + characteristicWriteType +
", timeoutMillis=" + timeoutMillis + ')');
if (serviceUuid == null)
{
throw new IllegalArgumentException("serviceUuid must not be null");
}
if (characteristicUuid == null)
{
throw new IllegalArgumentException("characteristicUuid must not be null");
}
if (value == null)
{
throw new IllegalArgumentException("value must not be null");
}
if (!connectIfDisconnected("characteristicWrite", timeoutMillis))
{
return;
}
final GattOperation operation = GattOperation.CharacteristicWrite;
final long startTimeMillis = timerStart(operation);
mHandlerBackground.post(new Runnable()
{
public void run()
{
try
{
Log.v(TAG, mDeviceAddressString +
" +characteristicWrite.run(): serviceUuid=" + serviceUuid +
", characteristicUuid=" + characteristicUuid +
", value=" + Arrays.toString(value) +
", characteristicWriteType=" + characteristicWriteType +
", timeoutMillis=" + timeoutMillis);
BluetoothGatt gatt = pendingOperationWaitReset("characteristicWrite", startTimeMillis);
if (gatt == null)
{
onDeviceCharacteristicWrite(serviceUuid, characteristicUuid, false);
return;
}
BluetoothGattService service = gatt.getService(serviceUuid);
if (service == null)
{
Log.e(TAG, mDeviceAddressString +
" characteristicWrite: gatt.getService(" + serviceUuid + ") returned null; failing");
onDeviceCharacteristicWrite(serviceUuid, characteristicUuid, false);
return;
}
BluetoothGattCharacteristic characteristic = service.getCharacteristic(characteristicUuid);
if (characteristic == null)
{
Log.e(TAG, mDeviceAddressString +
" characteristicWrite: service.getCharacteristic(" + characteristicUuid +
") failed");
onDeviceCharacteristicWrite(serviceUuid, characteristicUuid, false);
return;
}
if (characteristicWriteType != null)
{
int writeType;
switch (characteristicWriteType)
{
case WithoutResponse:
writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE;
break;
case Signed:
writeType = BluetoothGattCharacteristic.WRITE_TYPE_SIGNED;
break;
case DefaultWithResponse:
default:
writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT;
break;
}
characteristic.setWriteType(writeType);
}
if (!characteristic.setValue(value))
{
Log.e(TAG, mDeviceAddressString +
" characteristicWrite: characteristic.setValue(" + Arrays.toString(value) +
" failed for characteristic " + characteristicUuid);
onDeviceCharacteristicWrite(serviceUuid, characteristicUuid, false);
return;
}
if (!gatt.writeCharacteristic(characteristic))
{
Log.e(TAG, mDeviceAddressString +
" characteristicWrite: gatt.characteristicWrite(...) failed for characteristic " +
characteristicUuid);
onDeviceCharacteristicWrite(serviceUuid, characteristicUuid, false);
return;
}
pendingOperationWait(operation, timeoutMillis);
}
finally
{
Log.v(TAG, mDeviceAddressString +
" -characteristicWrite.run(): serviceUuid=" + serviceUuid +
", characteristicUuid=" + characteristicUuid +
", value=" + Arrays.toString(value) +
", characteristicWriteType=" + characteristicWriteType +
", timeoutMillis=" + timeoutMillis);
}
}
});
}