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

Xamarin.iOS调用Plugin.BLE的StartScanningForDevicesAsync崩溃求助

问题分析与解决方案

核心崩溃原因:iOS蓝牙权限缺失

iOS对蓝牙扫描/连接有严格的权限管控,这是调用StartScanningForDevicesAsync直接崩溃的最常见诱因。

必需权限说明

  • NSBluetoothAlwaysUsageDescription:iOS 13及以上版本,只要应用需要使用蓝牙(无论前台后台),必须在Info.plist中声明该权限并说明用途。
  • NSBluetoothPeripheralUsageDescription:针对iOS 12及以下版本的兼容权限,可同时添加以覆盖更多系统版本。

权限排查与配置步骤

  1. 检查并修改Info.plist
    右键项目中的Info.plist,选择「Open As」→「Source Code」,添加以下配置:

    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>需要访问蓝牙以连接Arduino设备</string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>需要访问蓝牙以连接Arduino设备</string>
    

    注意:权限说明字符串必须清晰告知用户用途,否则可能无法通过App Store审核。

  2. 主动检查并请求权限
    可以借助Plugin.Permissions NuGet包简化权限流程,在扫描前先确认权限状态:

    var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Bluetooth);
    if (status != PermissionStatus.Granted)
    {
        var result = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Bluetooth);
        if (result[Permission.Bluetooth] != PermissionStatus.Granted)
        {
            bt_state = "蓝牙权限未授予,无法扫描设备";
            return;
        }
    }
    

其他可能的崩溃诱因

  • UI线程操作违规:DeviceDiscovered事件在后台线程触发,直接修改devicelist(绑定UI的集合)会导致线程冲突,需切换到主线程更新:

    private void OnDeviceDiscovered(object sender, DeviceEventArgs e)
    {
        MainThread.BeginInvokeOnMainThread(() => {
            devicelist.Add(e.Device);
        });
    }
    
  • 重复绑定事件:每次点击按钮都注册DeviceDiscovered事件,会导致事件多次绑定,引发内存泄漏或逻辑混乱。建议注册前先解除旧绑定:

    _adapter.DeviceDiscovered -= OnDeviceDiscovered;
    _adapter.DeviceDiscovered += OnDeviceDiscovered;
    
  • 冗余状态判断:代码中同时判断!_adapter.IsScanning和!_handler.Adapter.IsScanning,二者指向同一适配器,保留一个判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:40:27