安卓蓝牙错误133

Posted

技术标签:

【中文标题】安卓蓝牙错误133【英文标题】:Android Bluetooth error 133 【发布时间】:2016-07-01 02:28:12 【问题描述】:

我正在尝试连接到 android 上的蓝牙设备。我在 onClientConnectionState 处理程序中收到状态 133。我并不总是得到这个错误 - 有时它连接得很好。我无法确定引发问题的原因。我什至在重新启动设备和我的 repro 应用程序后立即拥有它。

我知道几个问题和针对此问题的建议解决方案,包括(来自here、here 和 here):

为所有 BT API 使用 UI 线程 完成后务必关闭 GATT

但我正在做这一切。更重要的是,我的设备是 Nexus 5(运行 Lollipop),根据某些人的说法,它甚至不需要在 UI 线程上进行 BT 交互。

我已经整理了最简单的复制品。它在 C# 中,但 Java 等价物应该很明显:

[Activity(Label = "BluetoothGatt133ErrorRepro", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity

    protected override void OnCreate(Android.OS.Bundle bundle)
    
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.Main);
        var button = FindViewById<Button>(Resource.Id.button);
        button.Click += this.OnClick;
    

    private async void OnClick(object sender, EventArgs e)
    
        Action<string> log = message => Console.WriteLine($"***** #Environment.CurrentManagedThreadId message");

        log("Beginning");

        var bluetoothManager = (BluetoothManager)Application.Context.GetSystemService(Context.BluetoothService);
        var adapter = bluetoothManager.Adapter;
        var scanner = adapter.BluetoothLeScanner;
        var callback = new Callback();
        var filters = new List<ScanFilter>();
        var settings = new ScanSettings.Builder()
            .SetScanMode(global::Android.Bluetooth.LE.ScanMode.LowLatency)
            .Build();

        log("Starting scan");
        scanner.StartScan(filters, settings, callback);

        var result = await callback.Result;
        log($"Got device: result.Device.Name");

        var remoteDevice = adapter.GetRemoteDevice(result.Device.Address);
        var gattCallback = new GattCallback(log);

        log("Connecting GATT");

        var gatt = remoteDevice.ConnectGatt(Application.Context, true, gattCallback);
        gatt.Connect();

        await gattCallback.Result;

        log("Disconnecting GATT");

        gatt.Close();
        gatt.Dispose();
    

    private sealed class Callback : ScanCallback
    
        private readonly TaskCompletionSource<ScanResult> result;

        public Callback()
        
            this.result = new TaskCompletionSource<ScanResult>();
        

        public Task<ScanResult> Result => this.result.Task;

        public override void OnBatchScanResults(IList<ScanResult> results)
        
            foreach (var result in results)
            
                this.HandleResult(result);
            
        

        public override void OnScanResult(ScanCallbackType callbackType, ScanResult result)
        
            this.HandleResult(result);
        

        public override void OnScanFailed(ScanFailure errorCode)
        
            this.result.TrySetException(new InvalidOperationException($"Failed with error code errorCode."));
        

        private void HandleResult(ScanResult result)
        
            if (result.Device.Name.Contains("elided"))
            
                this.result.TrySetResult(result);
            
        
    

    private sealed class GattCallback : BluetoothGattCallback
    
        private readonly Action<string> log;
        private readonly TaskCompletionSource<bool> result;

        public GattCallback(Action<string> log)
        
            this.log = log;
            this.result = new TaskCompletionSource<bool>();
        

        public Task<bool> Result => this.result.Task;

        public override void OnConnectionStateChange(BluetoothGatt gatt, GattStatus status, ProfileState newState)
        
            this.log($"Connection state changed to newState with status status.");

            this.result.TrySetResult(true);
        
    

这是运行它的输出(我也留在了 Android 的 BluetoothGatt 源的输出中):

***** #1 Beginning
***** #1 Starting scan
07-01 11:53:21.458 D/BluetoothLeScanner(10377): onClientRegistered() - status=0 clientIf=5
***** #1 Got device: elided
***** #1 Connecting GATT
07-01 11:53:22.833 D/BluetoothGatt(10377): connect() - device: 00:00:DE:AD:BE:EF, auto: true
07-01 11:53:22.833 D/BluetoothGatt(10377): registerApp()
07-01 11:53:22.833 D/BluetoothGatt(10377): registerApp() - UUID=fa5bce8a-416d-47fe-9a8a-e44156f7e865
07-01 11:53:22.834 D/BluetoothGatt(10377): onClientRegistered() - status=0 clientIf=6
07-01 11:53:24.622 D/BluetoothGatt(10377): onClientConnectionState() - status=133 clientIf=6 device=00:00:DE:AD:BE:EF
***** #4 Connection state changed to Disconnected with status 133.
***** #1 Disconnecting GATT
07-01 11:53:24.707 D/BluetoothGatt(10377): close()
07-01 11:53:24.707 D/BluetoothGatt(10377): unregisterApp() - mClientIf=6

如您所见,我与蓝牙堆栈的所有交互都发生在主线程 (#1) 上。但尽管如此,我在 onClientConnectionState 处理程序中收到状态 133。

我的清单具有以下权限:

  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我正在使用最新的 Marshmallow 工具进行编译,目标是 Marshmallow,最低目标为 4.0.3(API 级别 15)。

这可能是什么原因?

【问题讨论】:

您能告诉我们您在清单文件中拥有哪些权限吗?您能否在尝试连接之前尝试停止扫描? ^^ 赞成停止扫描建议,没有注意到 @Zomb 为我的问题添加了更多详细信息。今天早上它对我来说显然工作正常,但下次弹出它时必须尝试停止扫描技巧。 【参考方案1】:

(注意:你可能已经这样做了,但我对 C# 不太熟悉)

根据我的经验,实际上并不是您只是在主线程上与 BLE 设备进行交互,只是您不会一次用太多请求淹没设备。

我曾经在 Android 上使用 BLE 时遇到过这个问题(并阅读了有关使用主线程的类似 cmets),这是因为我发布了太多请求(读/写、通知/指示注册等)在接收到 BluetoothGattCallback 对象中先前操作的回调之前,远程 Gatt 设备。我设置了自己的托管 gatt 操作队列(一个线程阻塞,直到在 GattCallback 中收到该操作的回调,或者初始读/写操作返回 false,然后处理下一个排队操作或使用退避乘数重试),因为我还没有遇到这个问题。据我所知,Android 在“排队”操作方面做得不好,所以“isBusy”布尔值会在不知不觉中咬住你(如果这没有跳出来,请查看 BlueoothGattCharacteristic 写入方法)。我还注意到您不想在回调对象中做太多工作,而是将回调委托给另一个线程或广播结果(因此您不会阻塞 Binder 线程)。通常我只是复制字节有效负载,并将其传递给另一个 HandlerThread 进行解析。

另外,是的,断开和关闭肯定非常重要。我通常使用 Service 来处理 BLE 交互,并在 Service 的 onDestroy 完成之前调用这两者。

【讨论】:

我的实际实现中已经有一个操作队列,但正如您在上面的测试应用程序中看到的那样,我什至没有走那么远。我在建立连接的第一个障碍时(经常,但并非总是)失败了。 另外,这总是你得到的结果,还是你曾经成功连接过? 抱歉,花了我一秒钟。有趣的。什么固件? 我的设备在测试期间崩溃后发生了这种情况,同时启用了远程设备的自动连接。大多数情况下,重新安装会修复它,您还针对什么 API 级别? 已为我的问题添加了更多详细信息。

以上是关于安卓蓝牙错误133的主要内容,如果未能解决你的问题,请参考以下文章

解决 安卓小程序蓝牙 重连失败的问题

如何估计两个安卓设备之间的距离? (蓝牙首选)

安卓怎样连接两个蓝牙?

安卓系统 蓝牙 与车载蓝牙的连接

unity在安卓手机上使用蓝牙连接arduino蓝牙模块

安卓蓝牙动态权限