You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin BluetoothLE插件运行异常:GattServer空引用异常排查

排查Xamarin.Forms中BluetoothLE插件的空引用异常

咱们一步步拆解这个问题,你碰到的空引用异常大概率是几个BLE开发常见坑叠加导致的,我帮你逐个排查:

1. 先修复异步方法调用的问题

你在OnCreate里调用BroadcastBluetooth时没有await,而且catch块是空的——这会导致两个关键问题:

  • 方法可能在Activity还没完全初始化完成时就执行,系统BLE服务还没准备好
  • 哪怕CrossBleAdapter.Current本身就是null,这个异常也被你吞了,根本看不到真正的根源

修复方式:
在Activity里用异步包装方法调用,并且不要吞异常,打印完整错误日志:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    // 先初始化插件(后面会说),再调用异步方法
    _ = StartBluetoothServerSafely();
}

private async Task StartBluetoothServerSafely()
{
    try
    {
        // 替换Task.Delay,等待蓝牙适配器真正就绪
        await CrossBleAdapter.Current.WhenStatusChanged()
            .FirstOrDefault(status => status == AdapterStatus.Ready);
            
        var server = CrossBleAdapter.Current.CreateGattServer();
        await server.Start(new AdvertisementData
        {
            LocalName = "TestServer",
            // 建议添加一个测试UUID,空列表可能导致部分设备广告失败
            ServiceUuids = new List<Guid> { Guid.NewGuid() }
        });
    }
    catch (Exception e)
    {
        // 打印完整异常栈,包括内部细节
        Android.Util.Log.Debug("BLE_CRASH", e.ToString());
        Console.WriteLine(e);
    }
}

2. 关键遗漏:插件必须初始化

这个蓝牙LE插件必须在Android项目中手动初始化,否则CrossBleAdapter.Current内部的系统服务引用会是空的,后续生成的GattServer对象自然会出问题。

添加初始化代码:
在MainActivity的OnCreate最开始(LoadApplication之前)加上:

// 传入当前Activity上下文,让插件绑定系统BLE服务
CrossBleAdapter.Current.Init(this);

3. 检查BLE权限和蓝牙状态

Android对BLE的权限控制很严格,不同版本要求不同:

  • Android 12+:需要BLUETOOTH_ADVERTISE、BLUETOOTH_CONNECT、BLUETOOTH_SCAN权限
  • Android 11及以下:需要BLUETOOTH、BLUETOOTH_ADMIN、ACCESS_FINE_LOCATION权限

在AndroidManifest.xml中添加权限:

<!-- 声明设备支持BLE硬件 -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

<!-- Android 12+ 专属权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

<!-- 兼容低版本Android的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />

另外要确保蓝牙已开启,可在代码中检查并引导用户开启:

if (CrossBleAdapter.Current.Status == AdapterStatus.Off)
{
    // 请求用户开启蓝牙
    await CrossBleAdapter.Current.RequestEnable();
}

4. 关于异常路径指向插件本地目录的说明

这个是正常现象,你使用的是预编译插件包,调试时栈追踪会显示插件开发者的本地源码路径,不用在意,解决前面几个问题后,空引用异常自然会消失。

总结排查步骤

  1. 给异步方法添加正确的await逻辑,不要吞异常,打印完整日志
  2. 在Android项目中初始化插件,传入Activity上下文
  3. 确认已添加对应Android版本的BLE权限
  4. 等待蓝牙适配器就绪后再创建GattServer
  5. 给广告数据添加非空的ServiceUUID列表

内容的提问来源于stack exchange,提问作者Drake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:00:30