Bluetooth LE(低功耗蓝牙) - 第四部分
回顾
在本系列前几篇文章中我们完成了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。
下期预告
一旦我们接受到与传感器已经连接的回调信息时,我们就可以与传感器进行通信了。我们将在下一篇文章中讨论这点。
本文的源代码可以在这里 找到。
Bluetooth LE(低功耗蓝牙) - 第四部分的更多相关文章
- Bluetooth LE(低功耗蓝牙) - 第一部分
前言 在写这篇文章的时候,谷歌刚刚发布了Android Wear ,摩托罗拉也发布了 Moto 360 智能手表.Android Wear的API还是相当基本的,是很好的文档材料,而且还会不断的更新, ...
- Bluetooth LE(低功耗蓝牙) - 第三部分
回顾 在本系列的前两篇文章中,我们已经了解了一些关于Bluetooth LE的背景并建立一个简单的Activity / Service框架. 在这篇文章中,我们将探讨Bluetooth LE的细节 ...
- Bluetooth LE(低功耗蓝牙) - 第二部分
回顾 在前面的文章中我们介绍了Bluetooth LE的背景也说明了我们在本系列文章中将要开发什么,但是还没有实际的代码.我们将在这篇文章中纠正这一点,我们将通过定义 Service/Activity ...
- Bluetooth LE(低功耗蓝牙) - 第五部分
回顾: 在本系列前面的文章中我们完成了发现BLE传感器并与之建立连接.现在只剩下从其中获取数据了,但是这并没有看起来那么简单.在这篇文章中我们将讨论GATT的特点以及如何促进主机与传感器之间的数据交换 ...
- Bluetooth LE(低功耗蓝牙) - 第六部分(完)
在本系列前面的文章中我们已经了解了,在我们从一个TI SensorTag中获取温度和湿度数据之前,我们需要经历的各种步骤.在本系列中的最后一篇文章,我们将完成注册并接收SensorTag的通知,并接收 ...
- Bluetooth Low Energy——蓝牙低功耗
Android4.3(API级别18)引入内置平台支持BLE的central角色,同时提供API和app应用程序用来发现设备,查询服务,和读/写characteristics.与传统蓝牙(Classi ...
- Android使用BLE(低功耗蓝牙,Bluetooth Low Energy)
背景 在学习BLE的过程中,积累了一些心得的DEMO,放到Github,形成本文.感兴趣的同学可以下载到源代码. github: https://github.com/vir56k/bluetooth ...
- 低功耗之战!ANT VS Bluetooth LE
利用近距离无线通信技术将手机及可穿戴式传感器终端等与智能电话连接起来,实现新的功能.最近,以此为目标的行动正在展开.其中备受关注的近距离无线方式是“ANT”和“Bluetooth LE”.为了在各种便 ...
- BLE——低功耗蓝牙(Bluetooth Low Energy)
1.简介 以下蓝牙协议特指低功耗蓝牙协议. 蓝牙协议是由SIG制定并维护的通信协议,蓝牙协议栈是蓝牙协议的具体实现. 各厂商都根据蓝牙协议实现了自己的一套函数库——蓝牙协议栈,所以不同厂商的蓝牙协议栈 ...
随机推荐
- MYSQL 基础操作
1.MySQL基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t1; --创建一个和t1一样的表,用like(表结构也一样 ...
- wordpress密码生成与登录密码验证
一.研究wordpress时wordpess的密码密码生成与登录密码验证方式很重要 WordPress密码已成为整合的首要目标,如何征服整合,就得了解WordPress密码算法. WordPress系 ...
- U3D 摄像机镜头控制
如果要实现,摄像机跟随着主角运动,还有运用滚轮实现镜头的方法和缩小的实现原理 方法1:把主摄像机放到主角的下面,作为一个子对象,调整好摄像机的视角,此时就会跟随了. 方法2:用代码让摄像机的相关的po ...
- c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量
一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址 ...
- oracle插入数据报错ORA-26026
今天进行数据清理时发现报错ORA-26026,主要是把从交易库提取数据并插入到归档库中. 检查一下发现是归档库的索引问题. 当时为了提高插入速度,所以删除了归档库的索引,可能对主键索引产生了影响. 解 ...
- QVW中实现日期区间的选择功能!
QV在日期的选择上不是很灵活,日期区段的选择可以在列表框中直接用鼠标拖拉区段,如果跨周期比较长了还是不是很方便啦. 下面介绍的方式是完全实现了起始日期的选择功能. 注:日期这个字段在抽取的时候一定要格 ...
- 如何解决在GDI画图中,多次修改画笔的颜色
首先创建个画笔对象: CPen gPen;gPen.CreatePen(PS_SOLID, 1, RGB(120,120,130));//一定灰度的画笔〈/br〉CPen* pOldPen = pDC ...
- 实现Action(含Action访问ServletAPI)
Action里是否包含实例变量不重要,重要的是包含setter和getter方法. Action可用于封装请求参数和处理结果.jsp中使用struts2输出:<s:property value= ...
- paramiko模块实现堡垒机
通过SSHClient 执行命令 """通过用户名密码验证""" import paramiko # 创建 SSH 对象 ssh = par ...
- 将图片文件转换为.py文件
最近用wxpython写了一个脚本,其中要给窗体设置图标文件,需要单独的一个ico文件,这样就比较影响美观,另外打包的时候还要将图标文件一起打包很繁琐.这时候看到wxpython文件有一个工具img2 ...