gpt4 book ai didi

java - 安卓蓝牙错误133

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:20:44 32 4
gpt4 key购买 nike

我正在尝试连接到 Android 上的蓝牙设备。我在我的 onClientConnectionState 处理程序中收到状态 133。我并不总是收到此错误 - 有时连接正常。我一直无法确定是什么触发了这个问题。我什至在重新启动设备和我的 repro 应用程序后立即拥有了它。

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

  • 为所有 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。

我的 list 具有这些权限:

  <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)。

这可能是什么原因造成的?

最佳答案

(注意:您可能已经在这样做了,但我对 C# 并不精通)

根据我的经验,您并不是真的只是在主线程上与 BLE 设备交互,只是您没有一次向设备发送太多请求。

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

此外,是的,断开连接和关闭确实非常重要。我通常使用服务来处理 BLE 交互,并在服务的 onDestroy 完成之前调用这两者。

关于java - 安卓蓝牙错误133,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38136103/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com