无法通过UUID找到BLE服务(代码中的UUID是正确的)

移动开发 2026-07-10

我最初用Python做这个BLE项目,但在Android权限方面遇到了问题,于是尝试用原生Kotlin编写一个Android应用(说实话……这种感觉)。它的核心是运行一个线程,重复按ID轮询某个特定的特征,并通过UDP发送数据。

到目前为止,它是在查找并连接设备:

            val device = bluetoothAdapter.getRemoteDevice(targetDeviceAddress)
            bluetoothGatt = device.connectGatt(context, false, gattCallback)

这触发了 onConnectionStateChange()。我知道这是因为蓝牙设备在此时有响应。

这会调用 gatt.discoverServices(),进而触发 onServicesDiscovered()

            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    val service = gatt.getService(UUID.fromString(targetServiceUuid))
                    if (service != null) {
                        targetCharacteristic = service.getCharacteristic(UUID.fromString(targetCharacteristicUuid))
                        _status.value = BleStatus.Connected
                    } else {
                        _status.value = BleStatus.Error("Service not found")
                    }
                } else {
                    _status.value = BleStatus.Error("Service discovery failed")
                }
            }

我之所以知道进入这个函数,是因为应用的状态框里会闪现“Service not found”。这是此字符串唯一出现的地方——所以它肯定是在尝试获取该服务(基于 targetServiceUuid,我已经通过列出设备的服务来验证),但没有找到。

也就是说——据我所知,我请求的是正确的服务UUID,但没有任何返回,我已经想不出办法。

在此之前,应用还请求Manifest.permission.BLUETOOTH_SCAN、Manifest.permission.BLUETOOTH_CONNECT和 Manifest.permission.ACCESS_FINE_LOCATION权限(我也在设置里检查了应用权限——它确实拥有“位置”和“附近设备”权限,因此我相信失败并非由于权限不足)。

这是OnePlus(Oppo)手机,Android 14。设备是BBC Micro:bit。

我到底还缺少什么?谢谢。

FURTHER INFORMATION:

补充信息:

经过进一步日志记录,我发现micro:bit的服务在电脑端的报告与手机端不同。

去掉无关结果,电脑端运行的python+bleak脚本报告说 e95d0753-251d-470a-a062-fa1922dfa9a8 (Handle: 40): MicroBit Accelerometer Service 存在。

但这个UUID在 Android环境中缺失。

Kotlin日志代码看起来是这样的:

                    val uuid = UUID.fromString(targetServiceUuid)
                    val lsb = uuid.getLeastSignificantBits()
                    val msb = uuid.getMostSignificantBits()
                    Log.i("mb2o", "targetServiceUuid string = %s".format(targetServiceUuid))
                    Log.i("mb2o", "lsb hex = %s".format(lsb.toHexString()))
                    Log.i("mb2o", "msb hex = %s".format(msb.toHexString()))

                    // this is poorly factored but will delete later
                    val srvIter = gatt.getServices().iterator()
                    while (srvIter.hasNext()) {
                        var srvc = srvIter.next()
                        Log.i("mb2o", "service = %s".format(srvc.uuid))
                    }

并输出

targetServiceUuid string = e95d0753-251d-470a-a062-fa1922dfa9a8
lsb hex = a062fa1922dfa9a8
msb hex = e95d0753251d470a
service = 00001800-0000-1000-8000-00805f9b34fb
service = 00001801-0000-1000-8000-00805f9b34fb
service = 0000fe59-0000-1000-8000-00805f9b34fb
service = e97dd91d-251d-470a-a062-fa1922dfa9a8
service = 0000180a-0000-1000-8000-00805f9b34fb
service = e95d93af-251d-470a-a062-fa1922dfa9a8

e95d93af-251d-470a-a062-fa1922dfa9a8 与之非常接近,但它对应的是micro:bit的事件服务,而不是加速度计。

这是一个令人困惑的结果。也许事件服务在这里会起作用。

解决方案

我对在onServicesDiscovered中查找特征时遇到的困难记得很模糊,曾经因为某些我记不清的原因需要把hibits和 lobits分别测试。不过这是我的代码:

      public void onServicesDiscovered(BluetoothGatt gatt, int status)
        {
        int n, k;
        long lobits, hibits;

        List<BluetoothGattService> servicelist;
        List<BluetoothGattCharacteristic> clist;
        BluetoothGattCharacteristic bchar;

        if (status == BluetoothGatt.GATT_SUCCESS)
          {
          servicelist = gatt.getServices();
          for (n = 0; n < servicelist.size(); ++n)
            {
            lobits = servicelist.get(n).getUuid().getLeastSignificantBits();
            hibits = servicelist.get(n).getUuid().getMostSignificantBits();

            if (hibits == 0x1122334455667788L && lobits == 0x99aabbccddeeffffL)
              {  // FOUND service 112233445566778899aabbccddeeffff
              clist = servicelist.get(n).getCharacteristics();
              for (k = 0; k < clist.size(); ++k)
                {
                bchar = clist.get(k);
                hibits = bchar.getUuid().getMostSignificantBits();
                if (hibits == 0x1122334455667788L)
                  {
                  lobits = bchar.getUuid().getLeastSignificantBits();
                  if (lobits == 0x99aabbccddeeff00L)
                    {
                    // FOUND characteristic bchar 112233445566778899aannccddeeff00
                    }
                  }
                }
              }
            }
          }   
        }
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章