OnServicesDiscovery中的Android BluetoothGatt.getServices(xyz)为onScanResult ScanRecord.getServiceUuids()中列出的服务xyz返回null

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

自2013/API18/4.3以来,我一直在Android上做BLE。
我知道我在做什么,但我不能解决这个简单的问题

我正在成功扫描可扩展设备,并在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);
            }
        }
    });
}