首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android蓝牙错误133

Android蓝牙错误133
EN

Stack Overflow用户
提问于 2016-07-01 02:28:12
回答 1查看 4.1K关注 0票数 5

我试图连接到Android上的蓝牙设备。在我的onClientConnectionState处理程序中,我正在接收状态133。我并不总能理解这个错误--有时候它联系得很好。我还没能说出是什么引起了这个问题。在重新启动设备和我的repro应用程序之后,我甚至立即得到了它。

我知道这个问题的几个问题并提出了解决方案,包括(来自hereherehere):

  • 对所有BT使用UI线程
  • 一定要关闭关贸总协定。

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

我已经把最简单的复制品整理好了。它是用C#编写的,但是Java的等价性应该是显而易见的:

代码语言:javascript
复制
[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源代码的输出):

代码语言:javascript
复制
***** #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。

我的清单具有以下权限:

代码语言:javascript
复制
  <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)。

是什么导致了这一切?

EN

回答 1

Stack Overflow用户

发布于 2016-07-01 02:41:50

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

在我的经验中,你并不是仅仅在主线程上与BLE设备交互,只是你没有一次用太多的请求淹没这个设备。

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

而且,是的,断开和关闭肯定是非常重要的。我通常使用一个服务来处理BLE交互,并在服务的onDestroy完成之前调用这两个交互。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38136103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档