Android:捕获BLE连接失败/断开连接? [英] Android: Catching BLE Connection Fails/Disconnects?

查看:588
本文介绍了Android:捕获BLE连接失败/断开连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,在正常情况下,我可以正常连接到BLE设备.我想做的是处理异常情况,例如与设备的连接失败或建立的连接丢失(可能是从悬崖上摔下来或被公共汽车撞上了).

我正在使用CyPress BLE模块进行测试,我正在做的测试之一是断开模块的电源.但是,onConnectionStateChange永远不会被调用!我所见到的一切都是成功的连接.它将花费数小时来尝试连接,并且永远不会明显放弃.我会延迟取消连接尝试,但是无法取消(我知道)蓝牙设备上的连接尝试!据我所知,它将一直尝试直到电池电量耗尽.

这是我的onConnectionStateChange现在在Gatt回调中的外观.请注意,我正在尝试捕获并记录涉及任何连接状态更改的任何类型的回调...除非连接成功,否则永远不会调用该回调.请注意,这不是活动本身的代码.它在一个单例持有的对象中. (我想在多个活动之间保持联系)

         @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            mGatt = gatt;
            Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "Status: "+status+ " Newstate: "+newState);
            switch(status)
            {
                case BluetoothGatt.GATT_SUCCESS:
                    mReconnectAttempts = MAX_ATTEMPTS;

                    if(newState == BluetoothGatt.STATE_CONNECTED)
                    {
                        DispatchEvent(Event.Type.BT_ON_CONNECT);
                        bIsConnected = true;
                        gatt.discoverServices();
                    } else if (newState == BluetoothGatt.STATE_DISCONNECTED)
                    {
                        DispatchEvent(Event.Type.BT_ON_DISCONNECT);
                        bIsConnected = false;
                    }
                    break;
                default:
                    if(newState == BluetoothGatt.STATE_DISCONNECTED)
                    {
                        bIsConnected = false;
                        if(mReconnectAttempts > 0)
                        { // if we have attempts left, auto attempt to reconnect
                            DispatchEvent(Event.Type.BT_RECONNECTING);
                            mReconnectAttempts--;
                            gatt.connect();
                            bIsConnected = false;
                        }
                        else
                        {
                            mReconnectAttempts = MAX_ATTEMPTS;
                            DispatchEvent(Event.Type.BT_ON_CONNECT_FAIL);
                            bIsConnected = false;
                        }
                    } else {
                        Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "onConnectionStateChange: Failed?");
                    }
            }

            super.onConnectionStateChange(gatt, status, newState);
        }
 

无法检测到断开连接是我代码中其他地方的问题,例如我显示一个进度对话框,表明该应用程序正在连接到BLE设备.好吧,该对话框永远不会消失,因为永远不会抛出连接失败"事件.

解决方案

我认为您正在寻找的是Bluetooth Supervision timeout,它根据这里是Android 5.1上Supervision Timeout的值.

没有API可以设置此参数,因此在关闭BLE模块电源后,您将需要等待20秒钟(取决于您的Android版本和设备)来获取状态为BluetoothGatt.STATE_DISCONNECTEDonConnectionStateChange回调

So I'm able to connect to a BLE device just fine under normal circumstances. What I want to do is handle abnormal circumstances, like when the connection to a device fails or an established connection is lost (maybe it got thrown off a cliff or hit by a bus)

I'm using a CyPress BLE module to test this, and one of the tests I'm doing is to remove power from the module. However, onConnectionStateChange never gets called! All I ever see it respond to is successful connections. It'll spend hours trying to connect and never give up evidently. I would do a delayed cancellation of the connection attempt, but there is no way to cancel the connection attempt on a Bluetooth device (that I know of)! As far as I can tell it'll keep trying until the battery runs down.

Here's what my onConnectionStateChange looks like right now, inside the Gatt Callback. Note that I'm trying to catch and log ANY kind of callback involving ANY kind of connection state change... which never gets called unless connection success. Note that this is code is not on the activity itself. It's in an object held by a singleton. (I want to maintain connection across multiple activities)

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            mGatt = gatt;
            Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "Status: "+status+ " Newstate: "+newState);
            switch(status)
            {
                case BluetoothGatt.GATT_SUCCESS:
                    mReconnectAttempts = MAX_ATTEMPTS;

                    if(newState == BluetoothGatt.STATE_CONNECTED)
                    {
                        DispatchEvent(Event.Type.BT_ON_CONNECT);
                        bIsConnected = true;
                        gatt.discoverServices();
                    } else if (newState == BluetoothGatt.STATE_DISCONNECTED)
                    {
                        DispatchEvent(Event.Type.BT_ON_DISCONNECT);
                        bIsConnected = false;
                    }
                    break;
                default:
                    if(newState == BluetoothGatt.STATE_DISCONNECTED)
                    {
                        bIsConnected = false;
                        if(mReconnectAttempts > 0)
                        { // if we have attempts left, auto attempt to reconnect
                            DispatchEvent(Event.Type.BT_RECONNECTING);
                            mReconnectAttempts--;
                            gatt.connect();
                            bIsConnected = false;
                        }
                        else
                        {
                            mReconnectAttempts = MAX_ATTEMPTS;
                            DispatchEvent(Event.Type.BT_ON_CONNECT_FAIL);
                            bIsConnected = false;
                        }
                    } else {
                        Logy.CallPrint(LOGY_ENABLE, CLASSNAME, "onConnectionStateChange: Failed?");
                    }
            }

            super.onConnectionStateChange(gatt, status, newState);
        }

Not being able to detect disconnects is an issue elsewhere in my code, like where I show a Progress Dialog indicating the app is connecting to a BLE device. Well, that dialog never goes away because the event "On Connect Fail" never gets thrown.

解决方案

I think what you are looking for is Bluetooth Supervision timeout which is according to Bluetooth LE specifications :

a parameter that defines the maximum time between two received Data Packet PDUs before the connection is considered lost

Default Supervision timeoout is set to 20 seconds on Android (depending on Android version & device). For instance, here is the value of Supervision Timeout on Android 5.1.

There is no API to set this parameter, so you will have to wait 20 seconds (depending on your Android version & device) to get onConnectionStateChange callback with status BluetoothGatt.STATE_DISCONNECTED after you power off your BLE module

这篇关于Android:捕获BLE连接失败/断开连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆