Android BluetoothGatt - 状态133 - 注册回调

ck1*_*221 39 android bluetooth-lowenergy gatt

首先我读了解答:GATT回调无法注册并采取该帖子中建议的步骤来解决此问题但没有成功.如果你还没有阅读它,那里的推荐修复是直接从主线程或使用处理程序进行所有BLE调用.

我正在开发一个BLE应用程序,希望运行一项执行以下任务的服务(每10秒调用一次活动):

1)Gets list of our products available to connect to (done, works)

2)For each available device:

          2a)connect to device
          2b)discover services
          2c)read 5 characteristics in this fashion:
             2c1)read characteristic
             2c2)onCharacteristicRead parse data
             2c3)when finished with data read next characteristic
             2c4)repeat until all are read (this is done using a state var and switch statement)
         2d)disconnect from device
         2e)connect to next device
         2f)repeat until all devices are read from
         2g)stopSelf()
Run Code Online (Sandbox Code Playgroud)

所以这个问题......一切都很有效.我可以执行整个服务启动{startService(...); 在mainActivity中完成{stopSelf(); 在服务中} 6次.

在第7次我得到BluetoothGatt无法注册回调.我不知道为什么我能成功运行6次然后在第7次失败.

请记住,我正在从主线程进行所有BLE调用,并且已在多个位置的日志cat中进行了确认.

这是我的代码大纲:

SERVICE.JAVA

private Handler handler = new Handler();
private BluetoothGatt cGatt = null;
private int unitIndex = 0; // keep track of currently connected unit
private int state = 0; //used to keep track of which characteristic to read next

public int onStartCommand(Intent intent, int flags, int startId) 
{
    Log.i(TAG, "Service Started...");
    //get ArrayList of units

    if(units.size > 0)
        handler.post(connectNextRunnable); //calls connectNextDevice()
    else
        stopSelf();   
}

private Runnable discoverServices = new Runnable()
{
    public void run()
    {
        cGatt.discoverServices();
    }
}

private Runnable readNextValue = new Runnable()
{
    public void run()
    {
        BluetoothGattCharacteristic c = null;
        switch(state)
        {
            //set c to appropriate characteristic
        default: // all characteristics read
            unitIndex++;
            handler.post(connectNextRunnable)
            return
        }

        cGatt.readCharacteristic(c);
    }
}

private void connectNextDevice()
{
    if(unitIndex == 0)
        store System.nanoTime in variable

    if(unitIndex >= units.size) //finished will all units
        stopSelf();

    if(unitIndex < units.size)
        cGatt.disconnect //if null
        cGatt.connectGatt(this, false, gattCallback)
}

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() 
{
    public void onConnectionStateChange() 
    {
        handler.post(discoverServices);
    }

    public void onServicesDeiscovered() 
    {
        handler.post(readNextValue);
    }

    public void onCharacteristicRead() 
    {
        ParseData();
    }

    private void ParseData()
    {
        //do stuff with data
        handler.post(readNextValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,就像我说的那样,所有BLE内容都是从主线程通过处理程序调用的.该服务从头到尾成功运行了6次.在第7次我得到那个哑巴没有注册回调.

如果您认为相关,我可以提供更多的logcat信息.我没有在原帖中因为我输出了大量信息来验证收到的数据等.

以下信息是从头到尾第7次运行我的服务的logcat信息.

08-15 12:00:10.746: I/PMIQ BTS(32027): Service Started...
08-15 12:00:10.746: I/PMIQ BTS(32027): Units: 1
08-15 12:00:10.746: D/AbsListView(32027): unregisterIRListener() is called 
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 0
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to pmIQ-IQ130_D93A
08-15 12:00:10.766: I/System.out(32027): main
08-15 12:00:10.766: D/BluetoothGatt(32027): connect() - device: 00:1E:C0:19:D9:3A, auto: false
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp()
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp() - UUID=e9d10870-4b09-451c-a9fa-c6b5f3594a77
08-15 12:00:10.766: I/BluetoothGatt(32027): Client registered, waiting for callback
08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0
08-15 12:00:10.766: I/PMIQ BTS(32027): CONECTION STATE CHANGED...Binder_2
**08-15 12:00:10.766: E/BluetoothGatt(32027): Failed to register callback**
08-15 12:00:10.766: I/PMIQ BTS(32027): Could not connect to null ... 257
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 1
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.766: I/PMIQ BTS(32027): Start Time: 4360642409647
08-15 12:00:10.766: I/PMIQ BTS(32027): End Time: 4360648970925
08-15 12:00:10.766: I/PMIQ BTS(32027): Difference: 6561278
08-15 12:00:10.766: I/PMIQ BTS(32027): Time to complete: 6
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.876: I/PMIQ BTS(32027): ...Service Destroyed
Run Code Online (Sandbox Code Playgroud)

如果你已经在这里,谢谢!我找不到任何有关状态= 133意味着什么的信息?!它只在回调失败时发生.每隔一次它是status = 0.

08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0
Run Code Online (Sandbox Code Playgroud)

如果有人甚至可以回答这个问题......它可能对我有很大帮助.或者,如果有人能告诉我为什么它只运行6次.任何见解或预感都可能有所帮助!

感谢大家!

ck1*_*221 57

好吧,我已经弄明白了.这个问题主要是对我阅读BluetoothGatt文档时的疏忽.我在打电话.disconnect(),但不是.close().由于Galaxy s4一次只能处理6个连接,我的服务只运行了6次.添加.close()到我的代码允许它正确关闭连接并释放那些使用过的连接.

消息来源让我更仔细地重读了文档!

因此,如果您有相同设备的重复连接,请记住在您的BluetoothGatt对象上使用.close()!

  • 133是GATT_ERROR(来源:https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-4.4.4_r2.0.1/stack/include/gatt_api.h) (11认同)
  • 你知道133意味着什么?我也找不到它的文件.. (5认同)
  • 答案是正确的,但它并没有解决所有可能的错误案例..至少对于我与心爱的人133的经历. (4认同)
  • @andrea.rinaldi错误**133**,你唯一能做的就是重试多次.这是唯一已知的解决方案. (3认同)
  • 是的,你是对的.但是在发生一些Gatt_Error序列之后,这也没有帮助(错误代码:133).任何建议! (2认同)

小智 14

经过几个月的研究和拔毛,我找到了一个通常没有谈到的解决方案.

您的正常连接请求如下所示:

cGatt.connectGatt(this, false, gattCallback);
Run Code Online (Sandbox Code Playgroud)

还有另一个版本的connectGatt命令,带有第4个参数.此参数指定要连接的蓝牙设备类型.我添加了一个"2"来指定我通过蓝牙LE连接.(它被称为"运输",请原谅我,如果我的解释不正确,但它解决了我所有的问题)

试试这个:

cGatt.connectGatt(this, false, gattCallback, 2);
Run Code Online (Sandbox Code Playgroud)

而BAM,现在我的#133梦魇已经结束了(我祈祷)!

  • 请注意,带有`transport`参数的`connectGatt`方法需要API级别23.您可以使用常量`BluetoothDevice.TRANSPORT_LE`而不是硬编码值2. (4认同)

郑松岚*_*郑松岚 9

Android 操作系统 < 6.0?

mBluetoothDevice.connectGatt(context, false, callback);
Run Code Online (Sandbox Code Playgroud)

Android 操作系统 >= 6.0?

mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);
Run Code Online (Sandbox Code Playgroud)

最终,需要硬件设备才能彻底解决这个问题。