首页 > 解决方案 > 为什么我的应用从不调用 BluetoothGattCallback.OnServicesDiscovered?

问题描述

我正在开发一个 Xamarin.Forms(版本 4.8.0.1687)跨平台应用程序,该应用程序需要能够使用蓝牙 LE 连接到自身的其他实例。我正在为 BLE 使用共享接口/特定于平台的实现模式。当它充当中心时尝试从 Android 读取服务时遇到了一个障碍:我无法发现设备上充当外围设备的服务,这意味着永远不会调用OnServicesDiscovered回调方法(至少,不是20 分钟内)。为了尝试隔离问题,我将连接/服务发现代码精简为一个极短的版本,但我仍然遇到问题。这些在我的BluetoothGattCallback派生实现中:

public override void OnConnectionStateChange(BluetoothGatt gatt, [GeneratedEnum] GattStatus status, [GeneratedEnum] ProfileState newState)
{
    base.OnConnectionStateChange(gatt, status, newState);

    if (ProfileState.Connected == newState)
    {
        Thread.Sleep(1001); // Several articles I've read recommend a delay of at least 600 ms before calling DiscoverServices
        gatt.DiscoverServices(); // a breakpoint set here is reliably triggered
    }
    else
    {
        gatt.Close();
    }
}

public override void OnServicesDiscovered(BluetoothGatt gatt, [GeneratedEnum] GattStatus status)
{
    base.OnServicesDiscovered(gatt, status); // a breakpoint set here is never triggered

    if (GattStatus.Success == status)
    {
        this.hasDiscoveredServices = true;
    }
}

我确信该服务已设置并包含在内,因为我可以从应用程序的 iOS 实例在同一设备上看到它并读取它的特征。很难想象我会在这么简单的事情中遗漏什么,但我希望有更多知识和经验的人能看到它是什么。

编辑:我发现一篇文章说如果外围设备表明它有能力,Android BLE API 将始终使用 BR/EDR,我想知道这是否是我的问题。我使用Java.Lang.Reflect挖掘出对connectGatt隐藏版本的引用,它允许您显式设置传输协议并且......没有乐趣。完全一样 - OnConnectionStateChange被调用,显然成功,但OnServicesDiscovered根本没有被调用。

编辑:我偶然发现,如果我在同一个外围广告会话或突发或任何正确的词期间连接、断开连接和再次连接,那么调用DiscoverServices确实会导致在一秒钟内调用OnServicesDiscovered,但BluetoothGatt.Services有没有元素。我不确定这是否是进步。

编辑:如果我只是一遍又一遍地运行相同的connect-disconnect-reconnect-discover-services,偶尔一次 - 也许10次尝试一次,或者15次?- 它确实发现了服务并填充了Services属性。对于实际使用,这显然不够好。有没有可能我只是在用糟糕的硬件进行测试?Android 只是底层的垃圾吗?

编辑:在全新的 Galaxy Tab S7 上,行为似乎完全相同。进一步试验,但在这一点上,我很想建议搁置 Android 项目。

标签: androidxamarin.formsandroid-bluetooth

解决方案


推荐阅读