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()
:蓝牙功能是否启用。
当发现蓝牙功能未启用时,如下调用设置启用蓝牙:
if
(!
mBluetoothAdapter
.isEnabled()) {
Intent enableIntent =
new
Intent(BluetoothAdapter.
ACTION_REQUEST_ENABLE
);
startActivityForResult(enableIntent,
REQUEST_ENABLE_BT
);
}
如果发现当前设备没有打开对外可见模式,则传递
Intent
来调用打开可发现模式,代码如下:
Intent
discoverableIntent =
new
Intent(BluetoothAdapter.
ACTION_REQUEST_DISCOVERABLE
);
discoverableIntent.putExtra(BluetoothAdapter.
EXTRA_DISCOVERABLE_DURATION
,
300);
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
在新版本中的进一步完善来学习使用。