Android BLE连接时间间隔

时间:2014-01-28 06:50:38

标签: android connection-pooling bluetooth-lowenergy l2cap

我正在使用Android BLE API在Nexus 4上开发BLE应用程序。我有几个问题/怀疑:

1)有没有办法设置/覆盖BLE中央设备的连接或通知间隔。我发现对于Android,默认连接间隔固定为7.5毫秒。有没有办法更改此连接/通知延迟间隔设置。

来源:http://processors.wiki.ti.com/index.php/Bluetooth_SensorTag?DCMP=lprf-stdroid&HQS=lprf-stdroid-pr-wiki1#Supported_Android_devices

2)在连接到远程设备时,我面临着在随机时间间隔后断开连接的问题。有许多人面临连接丢弃问题,说明当Android使用Android 4.3 API进行BLE连接时,android是不稳定的。对此有什么解决方案吗?

修改

我在这里观察到的是,当需要时间重新连接时,它会随着一些L2CAP日志而来......跟随日志

Trying to create a new connection laststate_ BOND_NONE
D/BluetoothGatt( 9620): connect() - device: 1C:BA:81:11:CA:36, auto: true
D/BluetoothGatt( 9620): registerApp()
D/BluetoothGatt( 9620): registerApp() - UUID=1a9a0911-4d5c-41dc-8ac0-0284ef550510
D/BtGatt.GattService( 3208): registerClient() - UUID=1adsds0911-4sdsc-41dc-8ac0-0sdsdf550510
D/BtGatt.btif( 3208): btif_gattc_register_app
D/BtGatt.btif( 3208): btgattc_handle_event: Event 1000
D/BtGatt.btif( 3208): btif_gattc_upstreams_evt: Event 0
D/BtGatt.GattService( 3208): onClientRegistered() - UUID=1a9a0911-4d5c-41dc-8ac0-0284ef550510, clientIf=5
D/BluetoothGatt( 9620): onClientRegistered() - status=0 clientIf=5
D/BtGatt.GattService( 3208): clientConnect() - address=1C:BA:8C:1E:CA:36, isDirect=true
D/BtGatt.btif( 3208): btif_gattc_open
D/BtGatt.btif( 3208): btgattc_handle_event: Event 1004
D/BtGatt.btif( 3208): btif_get_device_type: Device [1c:ba:8c:1e:ca:36] type 2, addr. type 0
W/bt-l2cap( 3208): L2CAP - LE - cannot start new connection at conn st: 3

任何想法如何通过L2CAP清除cahce?

5 个答案:

答案 0 :(得分:11)

当我研究Android BLE API时,我找不到用于更改连接间隔和监督超时的API(也许是奴隶延迟,从我的头脑中记不起来)。我确实需要更改这些,您必须从从属设备进行更改。

Ashwini的回答你可以忽略,他说的话根本就不正确。符合蓝牙4.0标准的主设备必须支持从7.5毫秒到4.0秒的连接间隔。从设备可以请求改变连接参数并发送连接参数更新请求,并且主设备将相应地更新连接参数。

另一方面,主人(在您的情况下是Android设备)可能有兴趣自行更改连接间隔,以节省电量,并且您希望将连接间隔更改为更轻松间隔。

在我看来,Android API甚至几个设备上的硬件实现还不成熟,并且在BLE的意义上使用BLE会在Android设备上吸引更多功能。在未来,我相信你会在API级别和主机和控制器的分区上看到更好的支持,这样即使移动设备的主CPU处于休眠状态,控制器也可以保持连接。这将节省大量电力,您可以24/7保持与BLE设备的连接,而不会对电池寿命造成任何重大限制。

答案 1 :(得分:5)

@Ashwini:正如上一篇评论中提到的连接间隔7.5,它在一段时间内工作得更好。一段时间后,出现L2CAP问题,除非重置蓝牙适配器,否则连接不起作用。此外,当禁用蓝牙适配器并以编程方式重新启用时,会发现一种奇怪的行为。我们在下面收到以下GKI错误:

> /GKI_LINUX( 2232): ##### ERROR : GKI_exception: GKI_exception(): Task State Table
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: TASK ID [0] task name [BTU] state [0]
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: TASK ID [1] task name [BTIF] state [1]
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: TASK ID [2] task name [A2DP-MEDIA] state [1]
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: GKI_exception 65531 Sending to unknown dest#####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: 
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): 
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: * GKI_exception(): 65531 Sending to unknown dest
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): ##### ERROR : GKI_exception: ***************
> 02-05 15:49:24.466 E/GKI_LINUX( 2232): #####

此外,这个createBond API是否有助于改善与BLE设备的连接(实际上不需要配对进行连接)?

答案 2 :(得分:2)

对于您的第一个问题,正如OneWorld所说,建议智能手机处理连接延迟间隔设置。此设置非常依赖于蓝牙硬件和设备。用于特定智能手机的堆栈。

关于断线问题,我也面临类似的问题。我认为,这是由于issue登录了指定的链接。当OS处理连接时配对,您无法取消配对设备,此后所有重新连接尝试都会失败。如果设备使用4.3上的私有API以编程方式配对(& unpaired),假设您已正确处理GATT连接,则不会发生这种情况。在android 4.4.2中,添加了createBond API用于配对。因此,使用4.4.2,通信工作非常顺利。

关于android上蓝牙低功耗的稳定性,我可以确认它非常不稳定。我测试了安装在Nexus 4& Nexus 5配有低能量传感器。尽管具有相同的OS版本4.4.2,但两个设备都给出了不同的连接结果。我观察到设备在Nexus 4上经过一段时间后断开连接,而Nexus 5的设备运行良好。

希望这可以帮助您解决问题。

答案 3 :(得分:2)

我遇到了与第二个问题相同的自动断线问题。解决问题的两种方法:

1)在运行应用程序之前,通过蓝牙设置手动将Android设备与远程设备配对。

2)或者您可以在代码中以编程方式对它们进行配对。这是我在网上找到的配对代码,对我有用

private void pairDevice(BluetoothDevice device) {
        try {
            Log.d("pairDevice()", "Start Pairing...");
            Method m = device.getClass()
                    .getMethod("createBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
            Log.d("pairDevice()", "Pairing finished.");
        } catch (Exception e) {
            Log.e("pairDevice()", e.getMessage());
        }
    }

答案 4 :(得分:2)

至于更改连接间隔:

由于Android Lollipop API等级21,您可以使用: requestConnectionPriority() 有3个级别:CONNECTION_PRIORITY_BALANCED,CONNECTION_PRIORITY_HIGH或CONNECTION_PRIORITY_LOW_POWER。

它仍然不像我们开发人员想要的那样多才多艺,但至少还有一些......