由于项目需要,笔者需要在安卓平台开发一个程序,能够用蓝牙和下层的单片机通讯。
出于测试目的,笔者先用两部均支持蓝牙的安卓设备进行设备间通讯实验,本文就是在这个实验基础上写就的。
查阅了一些参考书籍和博客文章,笔者很是失望,因为它们都是罗列代码(而且几乎都是套用安卓官方自带的那两个例子——API Guides 下的蓝牙指导代码和 samples 下的 BluetoothChat),但是并没有给出系统的宏观分析,让人颇感失望。
认真研读 API Guides 下的蓝牙指导代码后,笔者先绘制出了类图,然后在其指导下完成了整个实验程序的构建,其间当然多有反复与修改,作为程序员大家肯定都懂的——"三分编程,七分调试"。
1. 蓝牙是什么?
一种近距离无线通信协议,小功率蓝牙设备 (一般我们见到的都是) 的通讯速率约为 1Mbps,通讯距离为 10m。
2. 蓝牙分主从吗?
分的,蓝牙组网的方式是:1 主 (<8) 从。蓝牙组的网有个可爱的名字——"微微网"(piconet),蓝牙设备在微微网的地址(注意不是 mac 地址)是 3 位,因此一个微微网最多有 8 台被激活设备。设备的主从角色的分配是在组成微微网时临时确定的,不过蓝牙技术支持 "主从转换"。
3. 蓝牙设备都有哪些状态?
激活,呼吸,保持,休眠:功率依次递减。
我们先来看看一般的通讯模型是怎样的
打开 -》建立连接 -》通讯 -》断开连接 -》关闭
打开设备是一切工作的前提,建立连接需要保证两个蓝牙设备之间的可见性而搜索就是找寻周围的蓝牙设备(此操作比较占带宽,通讯时务必关掉),通讯就是把两个设备用某种方式连接起来(一主一从)然后发送消息与接收消息,最后需要断开连接,关闭设备。
据此,设计 UI 如下(接收消息按钮仅仅是为了美观,代码中并未实现什么功能):
这个程序仅用到了一个活动:
// 实现 OnClickListener 接口是一个技巧,这样在活动中给控件设置监听的时候直接传 this 就好了,代码会简洁许多
比较重要的是三个内部类:
// 这三个都是线程类,和蓝牙相关的会阻塞的操作都封装在它们中
代码写的不是很完善,但完全能够达到测试的功能
建议把代码复制下来,再用 IDE 工具查看,先看框架(outline),再看细节
// 看代码有迷惑的地方,再去看前面的类图,在树林中迷了路,此时需要登高四望
// 所有的输出均会打印到 logcat 中,用 System.out 过滤一下
// 注意:使用蓝牙,需要声明 BLUETOOTH 权限,如果需要扫描设备或者操作蓝牙设置,则还需要 BLUETOOTH_ADMIN 权限,本实验两个权限都需要
1. 拿出两台设备,安装好程序,完成配对 // 配对的过程需要人为操作,与这个程序没有关系
2. 两台设备均打开蓝牙(从系统界面或是这个程序的 "打开蓝牙按钮均可")
3. 一台设备通过 adb 连接到电脑,点击 "启动主机" 按钮
4. 在另一台设备点击 "启动从机" 按钮
5. 在这台设备点击 "发送消息" 按钮
6. 不出意外的话,logcat 的 System.out 会打印出三条记录——1,2,3
MainActivity.java
activity_main.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- android:orientation="vertical">
- <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content">
- <Button android:id="@+id/open" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="打开蓝牙" />
- <Button android:id="@+id/close" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="关闭蓝牙" />
- </LinearLayout>
- <Button android:id="@+id/search" android:layout_width="match_parent" android:layout_height="wrap_content"
- android:text="搜索蓝牙" />
- <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content">
- <Button android:id="@+id/server" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="启动主机" />
- <Button android:id="@+id/client" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="启动从机" />
- </LinearLayout>
- <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content">
- <Button android:id="@+id/send" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="发送消息" />
- <Button android:id="@+id/receive" android:layout_width="0dp" android:layout_height="wrap_content"
- android:layout_weight="1" android:text="接收消息" />
- </LinearLayout>
- <Button android:id="@+id/paired" android:layout_height="wrap_content"
- android:layout_width="match_parent" android:text="已配对蓝牙" />
- </LinearLayout>
来源: http://www.cnblogs.com/jelif/p/5843372.html