1. 概述
bluetooth 是几乎现在每部手机标准配备的功能,多用于耳机 mic 等设备与手机的连接,除此之外,还可以多部手机之间建立 bluetooth 通信,本文就通过 sdk 中带的一个聊天室的例程,来介绍一下 android 上的 bluetooth 的开发。
在 android1.x 的时候,相关 api 非常不完善,还不能简单的使用 bluetooth 开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法 bluetooth 协议栈。在 android2 以后,框架提供了一些官方 api 来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论 android2 后的 bluetooth 通信的 api 使用方法。
首先看聊天室的效果图:
2. bluetooth 通信 api 介绍
2.1. bluetooth 通信过程
2.2. bluetooth api 的主要方法
bluetoothadapter 类
bluetoothadapter.getdefaultadapter() :得到本地默认的 bluetoothadapter ,若返回为 null 则表示本地不支持蓝牙;
isdiscovering() :返回设备是否正在发现周围蓝牙设备;
canceldiscovery() :取消正在发现远程蓝牙设备的过程;
startdiscovery() :开始发现过程;
getscanmode() :得到本地蓝牙设备的 scan mode ;
getbondeddevices() :得到已配对的设备;
isenabled() :蓝牙功能是否启用。
当发现蓝牙功能未启用时,如下调用设置启用蓝牙:
如果发现当前设备没有打开对外可见模式,则传递 intent 来调用打开可发现模式,代码如下:
bluetoothdevice 类,此为对应的远程蓝牙 device
createrfcommsockettoservicerecord() :创建该 device 的 socket 。
bluetoothsocket 类
connect() :请求连接蓝牙。
getinputstream() :得到输入流,用于接收远程方信息。
getoutputstream() :得到输出流,发送给远程方的信息。
close() :关闭蓝牙连接。
inputstream 类:
read(byte[]) :以阻塞方式读取输入流。
outputstream 类:
write(byte[]) :将信息写入该输出流,发送给远程。
3. bluetoothchat 例程分析
google 提供的关于 bluetooth 开发的例程为 bluetoothchat ,使用截图可见本文一开始。除去配置及 ui 定义等文件,主程序文件共三个: bluetoothchat.java 、 bluetoothchatservice.java 以及 devicelistactivity.java ,详细功能可见下面的描述。
3.1. 整体调用关系序列图
3.2. bluetoothchat.java
例程的主 activity 。 oncreate() 得到本地 bluetoothadapter 设备,检查是否支持。 onstart() 中检查是否启用蓝牙,并请求启用,然后执行 setupchat() 。 setupchat() 中先对界面中的控件进行初始化增加点击监听器等,然创建 bluetoothchatservice 对象,该对象在整个应用过程中存在,并执行蓝牙连接建立、消息发送接受等实际的行为。
3.3. bluetoothchatservice.java
public synchronized void start() :
开启 macceptthread 线程,由于样例程序是仅 2 人的聊天过程,故之前先检测 mconnectthread 和 mconnectedthread 是否运行,运行则先退出这些线程。
public synchronized void connect(bluetoothdevice device) :
取消 connecting 和 connected 状态下的相关线程,然后运行新的 mconnectthread 线程。
public synchronized void connected(bluetoothsocket socket, bluetoothdevice device) :
开启一个 connectedthread 来管理对应的当前连接。之前先取消任意现存的 mconnectthread 、 mconnectedthread 、 macceptthread 线程,然后开启新 mconnectedthread ,传入当前刚刚接受的 socket 连接。最后通过 handler 来通知 ui 连接 ok 。
public synchronized void stop() :
停止所有相关线程,设当前状态为 none 。
public void write(byte[] out) :
在 state_connected 状态下,调用 mconnectedthread 里的 write 方法,写入 byte 。
private void connectionfailed() :
连接失败的时候处理,通知 ui ,并设为 state_listen 状态。
private void connectionlost() :
当连接失去的时候,设为 state_listen 状态并通知 ui 。
内部类:
private class acceptthread extends thread :
创建监听线程,准备接受新连接。使用阻塞方式,调用 bluetoothserversocket.accept() 。提供 cancel 方法关闭 socket 。
private class connectthread extends thread :
这是定义的连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。构造函数里通过 bluetoothdevice.createrfcommsockettoservicerecord() ,从待连接的 device 产生 bluetoothsocket. 然后在 run 方法中 connect ,成功后调用 bluetoothchatsevice 的 connected() 方法。定义 cancel() 在关闭线程时能够关闭相关 socket 。
private class connectedthread extends thread :
这个是双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。 run 方法中使用阻塞模式的 inputstream.read() 循环读取输入流, 然后 post 到 ui 线程中更新聊天消息。也提供了 write() 将聊天消息写入输出流传输至对方,传输成功后回写入 ui 线程。最后 cancel() 关闭连接的 socket 。
3.4. devicelistactivity.java
该类包含 ui 和操作的 activity 类,作用是得到系统默认蓝牙设备的已配对设备列表,以及搜索出的未配对的新设备的列表。然后提供点击后发出连接设备请求的功能。
除了 rfcomm 通信外, android 上关于 bluetooth 的还有 sdp 、 gap 、耳机设备连接等内容,本文还未涉及,将会随着蓝牙相关 api 在新版本中的进一步完善来学习使用。
从电动汽车续航痛点到安全挑战 SiC功率元器件的作用逐渐在显现
Step7组态实现以太网的S7通信
GT30J65MRB东芝分立IGBT将大幅提高空调和工业设备的效率
轻触开关电路的设计步骤?
Alphabet Q2财报公布,业绩表现良好
Android智能手机蓝牙通信功能开发:BluetoothChat例程分析
同盾科技陈文:探索数据安全应科技手段和制度管理并重
除诺基亚p1以外 诺基亚又一部神机3310 即将将在MWC诞生?
医疗产品设计可实时监测人体的身体状况
RS进一步增强网站功能,提升用户在线体验
日系家电三巨头齐巨亏:供过于求销售下滑
三星s8最新消息:小米员工诋毁三星S8指纹识别,小米MIX不也是后置指纹识别吗?
边缘计算网关及基于无线通信技术的电网应用
一文看懂工业智能相机的优势与发展趋势
李辉:基于新一代G6存储提速厦门数字经济
苹果公司因版权侵犯问题起诉了网络安全初创公司Corellium
IMC2023第六届中国智造数字科技大会圆满落幕!
水质监测技术在水利水环境的应用
青云科技:凭着对云计算热爱与执着,成功走出一条独立自主之路
一文了解热电偶温湿度传感器