Android上的蓝牙通信功能的开发:BluetoothChat例程分析

99
回复
1816674
查看
  [复制链接]

659

主题

2140

帖子

7478

安币

码皇(巴士元老)

Rank: 8Rank: 8

发表于 2011-10-5 16:42:52 | 显示全部楼层 |阅读模式
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() :蓝牙功能是否启用。
当发现蓝牙功能未启用时,如下调用设置启用蓝牙:
  1. if (! mBluetoothAdapter .isEnabled()) {
  2.             Intent enableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_ENABLE );
  3.             startActivityForResult(enableIntent, REQUEST_ENABLE_BT );
  4.         }
复制代码
如果发现当前设备没有打开对外可见模式,则传递 Intent 来调用打开可发现模式,代码如下:
  1. Intent discoverableIntent = new Intent(BluetoothAdapter. ACTION_REQUEST_DISCOVERABLE );            discoverableIntent.putExtra(BluetoothAdapter. EXTRA_DISCOVERABLE_DURATION , 300);
  2. startActivity(discoverableIntent);
复制代码
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 在新版本中的进一步完善来学习使用。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

6

主题

161

帖子

418

安币

攻城狮

Rank: 3Rank: 3

QQ达人

发表于 2012-3-20 14:57:21 | 显示全部楼层
{:soso_e113:}

19

主题

290

帖子

396

安币

攻城狮

Rank: 3Rank: 3

发表于 2012-1-31 11:22:08 | 显示全部楼层
code呢??

35

主题

365

帖子

1212

安币

Android大神

Rank: 6Rank: 6

发表于 2012-3-4 22:39:10 | 显示全部楼层
好东西,代码在SDK里面的哦,楼上

0

主题

280

帖子

14

安币

程序猿

Rank: 2

QQ达人

发表于 2012-3-11 15:34:48 | 显示全部楼层
谢谢分享

0

主题

44

帖子

77

安币

程序猿

Rank: 2

发表于 2012-3-20 14:58:55 | 显示全部楼层
{:soso__16531217094629238310_3:}给力。。。

0

主题

103

帖子

157

安币

程序猿

Rank: 2

发表于 2012-3-20 15:05:29 | 显示全部楼层
学习了……

0

主题

71

帖子

69

安币

程序猿

Rank: 2

发表于 2012-3-20 15:07:50 | 显示全部楼层
very good!!!!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )