回顾
在本系列前几篇文章中我们完成了BLE设备的发现 , 为我们的app通过BLE显示从TI SensorTag设备中获取到环境温度和湿度的工作打下了基础。在这篇文章中我们将着眼于连接到我们所发现的SensorTag设备。
与BLE设备建立连接
每一个熟悉传统蓝牙的开发者都将注意到蓝牙配置信息。对于那些蓝牙开发的新手来说,配置文件是一个用于规范行为的准则。例如, Advanced Audio Distribution Profile (A2DP 高级音频分发配置[我怎么感觉翻译成"协议"会更好一点呢?]) 允许支持A2DP规范的两个设备以流的形式向另一个设备传输音频信息。
在BLE中有一个标准的配置文件,称为 Generic ATTribute Profile(简称为GATT, 通用属性配置文件),它提供了一种通过BLE有效地共享原子数据的标准化机制。在本系列文章的后面我们将深入讨论GATT协议,但我们将要连接的运行BLE的任何传感器都将包含GATT服务器以便我们的设备与传感器交换数据。
连接到GATT服务器实际上是一个二阶段过程。首先我们必须创建和打开一个代表了GATT服务器的本地代理实例的连接,然后我们必须将这个代理连接到传感器上的GATT服务器。为了创建代理实例,我们需要调用已发现的蓝牙设备BluetoothDevice 实例的connectGatt()
方法 。该方法接收三个参数。第一个是 Context ; 二是一个名为 autoConnect 的布尔值;第三是一个BluetoothGattCallback 的实例。最后一个参数表示调用该方法是异步的,从UI线程调用是安全的,因为网络操作将在后台线程上自动执行,一旦执行完成将执行 BluetoothGattCallback 的回调。 connectGatt() 的返回值是一个BluetoothGatt的实例,通过这个本地的代理对象,我们就可以与传感器上的GATT服务器通信了。
如果我们在调用 connectGatt()方法是将autoConnect
参数设置为 FALSE ,它将返回一个BluetoothGatt 对象,但是当连接到GATT服务器的时候不会接受回调。这也是预料中的,因为在这时我们只创建了本地代理。我们需要调用BluetoothGatt 对象的方法connect() 将本地代理连接到远程GATT服务器上,并且一旦完成,我们将接收到回调信息。只有这一个远程连接是异步的,因为它是唯一的一个阻塞式的网络调用。
有关GATT服务器,理解本地和远程组件是非常重要的,但是现在我们已经了解,有一个简单的连接方式。如果我们将autoConnect
参数设置为TRUE,那么它会自动连接到传感器上的GATT服务器。connectGatt()方法将很快返回,一旦远程连接完成我们随后会收到一个回调。关于autoConnect
的另一个好处是,如果和传感器失去连接,本地代理将试图恢复连接而对我们没有任何提示。我们要做的就是监控当前连接状态,只有当与传感器有交互时,才表示已经连接上了。
private BluetoothGatt mGatt = null; public void connect(String macAddress) { BluetoothDevice device = mDevices.get(macAddress); if(device != null) { mGatt = device.connectGatt(this, true, mGattCallback); } }
现在我们需要添加必要的回调以响应连接状态的变化。在 BluetoothGattCallback中还有一些其他的回调方法我们将在以后讨论,但现在我们只需要关心 连接/断开 状态的变化:
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); Log.v(TAG, "Connection State Changed: " + (newState == BluetoothProfile.STATE_CONNECTED ? "Connected" : "Disconnected")); if(newState == BluetoothProfile.STATE_CONNECTED) { setState(State.CONNECTED); } else { setState(State.IDLE); } } };
再次说明,我不去关心我们的UI中做了什么因为本文的重点是BLE,但是当BleService中的设备状态变化时一个消息被发送到Activity使Activity可以相应地更新UI。
下期预告
一旦我们接受到与传感器已经连接的回调信息时,我们就可以与传感器进行通信了。我们将在下一篇文章中讨论这点。
本文的源代码可以在这里 找到。