蓝牙协议
蓝牙是使用工业、科学以及医学上通用的2.4-2.5GHz的无线发射频段,这一频段无需授权并全球通用。当蓝牙设备互相连接时,他们将组成一个微微网(piconet),以一个主设备和最大7个从设备的形式动态创建网络,最多共八个设备。
蓝牙协议栈就是通过软件栈映射硬件栈来实现的。
在JAVA中,我们感兴趣的是服务发现协议SDP。
无线应用程序
(虚拟名片、日历,蓝牙对战游戏等)
|
JAVA APIs for Bluetooth Wireless Technology
(JSR 082)
|
对象交换协议
OBEX
|
串口仿真协议
RFCOMM
|
服务发现协议
SDP
|
逻辑链路控制和适配协议
L2CAP
|
蓝牙主机控制接口
HCI
|
链路管理协议
LMP
|
基带
BB
|
蓝牙天线收发器
BR
|
软件实现
|
硬件实现
|
高
端
应
用层
|
中
间
协议层
|
底层硬件模块
|
蓝牙应用的基本框架
初始化
|
查找设备和服务
|
消费服务
|
创建服务
|
等待并处理连接
|
删除服务
|
1
|
2
客户端
|
3
服务端
|
1. 应用程序初始化蓝牙协议栈。
2. 客户端先查找附近的设备,然后对每个设备查找感兴趣的服务。然后即可以消费找到的服务。
3. 服务端先创建服务,然后对创建的服务进行注册到(SDDB),并等待客户端的连接,在客户接入后处理客户的连接。当不需要服务时可以删除服务。
Bluetooth API
Bluetooth的API位与WTK的lib目录下的jsr082.jar包中,是J2ME的可选包,在javax.bluetooth中,我们可以看到蓝牙应用所需要的三部分API:蓝牙发现、设备管理和蓝牙通信。
蓝牙发现
客户端程序使用服务代理类(DiscoveryAgent)来支持设备与服务的发现。当设备和服务被发现时,想得到通知的客户端应用程序必须实现并注册DiscoveryListener接口,这个接口定义了设备发现通知和服务发现通知的回调。
设备发现:
使用DiscoveryAgent类的"设备发现"方法来开始和取消设备发现:
.startInquiry() 启动发现附近设备,也叫inquiry
.cancelInquiry()取消当前进行的任何请求
蓝牙发现代理在请求阶段的不同时候会分别调用DiscoveryListener(发现监听器)不同的回调方法:
.deviceDiscovered() 指出是否有设备被发现。
.inquiryCompleted() 指出是否请求已经成功、触发一个错误或已被取消。
服务发现:
使用发现代理的服务发现方法来开始或取消服务发现:
. searchServices()启动服务发现搜索。
. cancelServiceSearch()取消在正在进行中的任何的服务发现搜索操作。
蓝牙发现代理在服务发现阶段的不同时候会分别调用DiscoveryListener的服务发现回调方法:
蓝牙发现代理在服务发现阶段的不同时候会分别调用DiscoveryListener的服务发现回调方法:
. servicesDiscovered() 表示是否服务已被发现。
. serviceSearchCompleted()表示服务发现是否已经完成。
UUID
类:
在蓝牙中,每个服务和服务属性都唯一地由"全球唯一标识符" (UUID)来校验。UUID类可表现为短整形(16或32位)和长整形(128位)UUID。例如:F0E0D0C0B0A000908070605040302010。文档上说在Windows下则执行命令uuidgen可取的UUID 。
SDDB
和
ServiceRecord
接口
:
SDDB由蓝牙实现负责维护的数据库。它包含了服务记录(service records),
ServiceRecord代表了对客户端有效的服务。每一条服务记录包含了描述服务细节的属性。这个类提供了几种有用的方法:
.getAttributeIDs() 和 getAttributeValue()方法返回服务记录的属性。
.getConnectionURL()方法获取链接的URL地址给服务器主机来收集服务记录。
.getHostDevice() 方法获取提供服务的远端设备。
为使服务端可以被客户端来使用,服务应用程序要通过如下方法建立一个服务记录,首先要创建一个连接通知器(connection notifier),然后由调用连接通知器的acceptAndWait()方法来向SDDB中插入记录。
设备管理
有
3
个主要的类来支持设备管理:
.LocalDevice
本地设备类
.RemoteDevice
远端设备类
.DeviceClass
一个设备的设备类
蓝牙通信
L2CAP
中的处理细节像消息分割和重组(
SAR
),多路连接。蓝牙连接都是基于通用连接框架(
GCF
)的,直接通过向接口和类的层次去创建连接和执行
IO
命令。
如同所有的
GCF
连接类型,你可以通过调用
GCF
连接工厂方法
javax.microedition.io.Connector
创建蓝牙连接。传递给
Connector()
方法的连接
URL
决定了要创建的连接类型:
一个
L2CAPConnection
连接的
URL
格式:
btspp://hostname:[CN | UUID];parameters
例如:
btspp://localhost:UUID
authenticate=false;authorize=false;encrypt=false;
实例:bit
(demo)在N6260上可以收发数据。
注意事项
1. 在创建服务、查找服务和处理连接时为了防止死锁或阻塞,务必使用多线程,新开线程来处理。
2. 在使用线程时接受发送数据时,注意线程间的同步。
3. 关于调试:由于jsr082.jar是个可选包,所以在WTK中注意选上蓝牙包。
4. 局限性:目前支持的手机就K750,S60,L6,L7,E2,N7370等机型,还有各终端厂商的蓝牙底层实现不一,互连可能不稳定。
5. 目前遇到的问题:时常掉线丢包。