Android BluetoothGatt - 状态 133 - 注册回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25330938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:20:58  来源:igfitidea点击:

Android BluetoothGatt - status 133 - register callback

androidbluetooth-lowenergygatt

提问by ck1221

First of all I read SOLVED: GATT callback fails to registerand took the steps suggested in that post to solve this issue with no success. The recommended fix in there if you haven't read it is to make all BLE calls from the main thread directly or with a handler.

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

I am working on a BLE app want to run a service (called from activity once every 10 seconds) that performs these tasks:

我正在开发一个 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()

So the issue... Everything works great for a little bit. I can perform the entire service start {startService(...); in mainActivity}to finish {stopSelf(); in Service}6 times.

所以问题......一切都很好。我可以执行整个服务 start {startService(...); 在 mainActivity}中完成{stopSelf(); 在服务}6 次。

On the 7th time I get BluetoothGatt Failed to register callback. I'm not sure why I can run it 6 times successfully and then fail on the 7th time.

第 7 次我收到 BluetoothGatt 注册回调失败。我不知道为什么我可以成功运行它 6 次,然后在第 7 次失败。

Keep in mind I am making all BLE calls from the main thread, and that has been confirmed in the log cat from multiple locations.

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

Here is an outline of my code:

这是我的代码的大纲:

SERVICE.JAVA

服务.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);
    }
}

So, like I have said, all BLE stuff is called from the main thread through a handler. The service successfully runs 6 times from start to finish. On the 7th time I get that dumb failed to register callback.

所以,就像我说的,所有 BLE 的东西都是通过一个处理程序从主线程调用的。该服务从头到尾成功运行了 6 次。在第 7 次我得到那个愚蠢的未能注册回调。

I can provide more logcat information if you think it is relevant. I did not in the original post because I am output a lot of information to it to verify data received etc..

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

The information below is the logcat information for the 7th run of my service from start to finish.

下面的信息是我的服务从头到尾第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

If you have made it here, thanks! I could not find ANY information on what status=133 means?! It only happens when the callback fails. Every other time it is status=0.

如果你在这里成功了,谢谢!我找不到有关 status=133 是什么意思的任何信息?!它仅在回调失败时发生。每隔一次状态为 0。

08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0

If anyone could even answer this.. it may help me greatly. Or if anyone can tell me why it only runs 6 times. Any insight or hunch could be helpful!

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

Thanks everyone!

谢谢大家!

回答by ck1221

Alright I have figured it out. The issue was mainly an oversight of when I was reading through the BluetoothGattdocumentation. I was calling .disconnect(), but not .close(). Since the Galaxy s4 can only handle 6 connections at a time, my service was only running 6 times. Adding the .close()to my code allowed it to properly shut down the connection and freed up those used connections.

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

Source that made me re-read the docs more carefully!

让我更仔细地重新阅读文档的来源!

So remember to use .close() on your BluetoothGatt object if you have a recurring connection to the same device(s)!!

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

回答by btmcmahan

After months of research and pulling my hair out, I have found a solution that is not normally talked about.

经过几个月的研究和拔毛,我找到了一个通常不会被谈论的解决方案。

Your normal connect request looks something like this:

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

cGatt.connectGatt(this, false, gattCallback);

There is another version of the connectGatt command, with a 4th parameter. This parameter specifies what type of bluetooth device you are connecting to. I added a "2" to specify that I am connecting via Bluetooth LE. (it's called "transport", forgive me if my explanation is incorrect, but it solved all my problems)

还有另一个版本的 connectGatt 命令,带有第四个参数。此参数指定您要连接的蓝牙设备类型。我添加了一个“2”来指定我通过蓝牙 LE 连接。(它叫“运输”,如果我的解释有误请见谅,但它解决了我所有的问题)

Try this:

尝试这个:

cGatt.connectGatt(this, false, gattCallback, 2);

And BAM, now my #133 nightmare is over (I pray)!

BAM,现在我的#133 噩梦结束了(我祈祷)!

回答by u4501068

Android OS < 6.0:

安卓操作系统 < 6.0:

mBluetoothDevice.connectGatt(context, false, callback);

Android OS >= 6.0:

安卓操作系统 >= 6.0:

mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);

Ultimately, hardware equipment is needed to completely solve this problem.

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

回答by user1278366

  • On some devices, it got fixed with mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);

  • on some devices like Samsung S7, A8, it was a problem with the ScanSettings.Builder().setReportDelay(400) // or 500ms. it should not be 0 or more like 1000ms. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_BALANCED) .setReportDelay(400) .build();

  • 在某些设备上,它得到了修复 mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);

  • 在三星 S7、A8 等某些设备上,ScanSettings.Builder().setReportDelay(400) // 或 500 毫秒存在问题。它不应该是 0 或更多,比如 1000 毫秒。 ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_BALANCED) .setReportDelay(400) .build();

回答by Artem Kabakov

Try to use next workaround:

尝试使用下一个解决方法:

private static boolean gatt_status_133 = false;

final Handler handler = new Handler();

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

    if (newState == BluetoothProfile.STATE_CONNECTED) {
        mConnectionState = STATE_CONNECTED;
        Log.i(TAG, "Connected to GATT server.");
        // Attempts to discover services after successful connection.
        Log.i(TAG, "Attempting to start service discovery:" +
                mBluetoothGatt.discoverServices());

    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
        if(status == 133)
        {
            gatt_status_133=true;
        }
        else{
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server."); 
        }
    }
}


@RequiresApi(api = Build.VERSION_CODES.M)
public boolean connect(final String address) {
    if (mBluetoothAdapter == null || address == null) {
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    // Previously connected device.  Try to reconnect.
    if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
            && mBluetoothGatt != null) {
        Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (mBluetoothGatt.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        } else {
            return false;
        }
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }

    mBluetoothGatt= device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
    Log.d(TAG, "Trying to create a new connection.");
    mBluetoothDeviceAddress = address;
    mConnectionState = STATE_CONNECTING;

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if(gatt_status_133)
            {
                Log.d(TAG, "Catch issue");
                connect(address);
                gatt_status_133=false;
            }
        }
    }, 4000);

    return true;
}