任繼濤,劉麗娜
摘要:介紹了Java藍牙無線技術(shù)API規(guī)范JSR82,并給出了采用JSR82規(guī)范開發(fā)藍牙無線應(yīng)用程序的具體實現(xiàn)方法和部分實例代碼。
關(guān)鍵詞:藍牙;Java;JSR82
中圖分類號:TP393文獻標識碼:A 文章編號:1009-3044(2009)34-9855-02
藍牙是一種低成本、短距離的無線通信技術(shù),主要是為手機、PDA,GPS等移動設(shè)備提供相互通信的能力。藍牙標準是一項開放標準,由藍牙技術(shù)聯(lián)盟負責(zé)管理。藍牙技術(shù)目前的最新版本為2.1,相比Wi-Fi、WiMAX、3G等無線技術(shù),藍牙芯片在功耗、成本和體積上占有優(yōu)勢。目前藍牙技術(shù)在手機、GPS和車載設(shè)備應(yīng)用上越來越廣泛,發(fā)展?jié)摿薮?目前大多數(shù)手機已集成藍牙芯片并支持Java應(yīng)用,使得采用Java技術(shù)開發(fā)手機藍牙無線應(yīng)用程序極為方便。
1 JSR82規(guī)范
2002年,Java開發(fā)社區(qū)發(fā)布了基于Java平臺的藍牙API規(guī)范JSR82。JSR82規(guī)范對支持JAVA嵌入式設(shè)備的JAVA應(yīng)用編程接口做出了明確規(guī)定,提供了一系列的標準API,可以幫助JAVA嵌入式設(shè)備無縫集成藍牙環(huán)境。
Java藍牙無線技術(shù)API包含兩個包,javax.bluetooth和javax.obex。javax.bluetooth包含了核心的藍牙API,如藍牙設(shè)備管理,藍牙設(shè)備發(fā)現(xiàn),藍牙服務(wù)查找、L2CAP等類。javax.obex屬于高級API,是一個不依賴于藍牙核心API的數(shù)據(jù)交換包。
javax.bluetooth包定義了4個接口,6個類和3個異常。其中LocalDevice類、RemoteDevice類和DeviceClass類屬于設(shè)備管理API;UUID類、DataElement類、Discorylistener接口、DiscoveryAgent類和SeviceRecord接口屬于服務(wù)發(fā)現(xiàn)API;L2CAPconnection接口和L2CAPconnectionNotifier接口屬于連接API。
2 藍牙應(yīng)用程序模型
每一個藍牙應(yīng)用都表現(xiàn)為一個藍牙服務(wù),提供服務(wù)的一方為服務(wù)端,消費服務(wù)的一方為客戶端。藍牙客戶端的行為包括初始化、發(fā)現(xiàn)周圍服務(wù)和設(shè)備、消費服務(wù)等,藍牙服務(wù)端的行為包括初始化、創(chuàng)建服務(wù)、注冊服務(wù)、等待客戶端訪問、創(chuàng)建連接提供客戶端消費等。
具備藍牙功能的應(yīng)用程序必須先要初始化藍牙堆棧,一個客戶端對遠端服務(wù)進行消費時首先要發(fā)現(xiàn)所有附近的設(shè)備,然后對每一個發(fā)現(xiàn)的設(shè)備搜索它感興趣的服務(wù),而提供服務(wù)的服務(wù)端在服務(wù)發(fā)現(xiàn)數(shù)據(jù)庫(SDDB,Service Discovery Database)中對客戶端進行注冊,對他們進行有效廣播,然后等待引入的連接,在他們進入時接受他們并為他們提供服務(wù)。最后,當不再需要服務(wù)時,應(yīng)用程序會在服務(wù)發(fā)現(xiàn)數(shù)據(jù)庫中將他們移除。
2.1 初始化
無論藍牙客戶端還是服務(wù)端,都首先要進行初始化,通常為初始化UUID類、獲得LocalDevice類等操作。服務(wù)端需要設(shè)置LocalDevice,讓設(shè)備處于可發(fā)現(xiàn)狀態(tài),設(shè)置發(fā)現(xiàn)模式,而客戶端不用設(shè)置發(fā)現(xiàn)模式。
在javax.bluetooth中,UUID類用來唯一識別一個藍牙服務(wù),每一個這樣的標識符都要在時空上保證唯一。UUID類有16位或32位的簡短UUID或128位的完整UUID。一般在創(chuàng)建時要生成自己的UUID,在服務(wù)搜索時要同時給出指定的UUID和通信協(xié)議的UUID。
設(shè)備管理API中的LocalDevice類代表本地藍牙設(shè)備,初始化時首先通過getLocalDevice()方法取得LocalDevice對象實例,然后調(diào)用setDiscoverable()方法設(shè)置發(fā)現(xiàn)模式。有三種發(fā)現(xiàn)模式:DiscoveryAgent.GIAC代表無時間限制模式,DiscoveryAgent.LIAC代表在規(guī)定的時間內(nèi)可被搜索,超時就進入不可搜索狀態(tài),DiscoveryAgent.NOT_DISCOVERABLE代表不可搜索狀態(tài)。
示例代碼如下:
uuid = new UUID("F0E0D0C0B0A000908070605040302010", false);//設(shè)置UUID
ld=LocalDevice.getLocalDevice();//取得本地設(shè)備實例
ld.setDiscoverable(DiscoveryAgent.GIAC);//設(shè)置可發(fā)現(xiàn)模式為無時間限制模式
localBTAddress=ld.getBluetoothAddress(); //取得藍牙設(shè)備地址
localBTName= ld.getFriendlyName(); //取得藍牙設(shè)備名稱
RemoteDevice類代表了遠端設(shè)備,它提供了讀取遠端設(shè)備藍牙地址和藍牙名稱的方法。
2.2 服務(wù)端操作
1)創(chuàng)建服務(wù)并注冊:利用UUID計算URL,創(chuàng)建L2CAPConnectionNotifier 連接(對應(yīng)L2CAP)或StreamConnectionNotifier連接(對應(yīng)SPP)。利用LocaIDevice取得對應(yīng)此L2CAPConneCtionNotifier 連接的服務(wù)ServiceRecord。如有必要,可以使用DataElement 來設(shè)置ServiceRecord的屬性。
2)等待客戶訪問:調(diào)用ConnectionNotifier 的方法,等待連接。
2.3 客戶端操作
1)發(fā)現(xiàn)周圍設(shè)備和服務(wù):在藍牙網(wǎng)絡(luò)中,客戶端通常不能直接得到服務(wù)端的藍牙地址,要使用服務(wù)發(fā)現(xiàn)API搜索周圍的設(shè)備和服務(wù)。為消費一項指定的服務(wù),客戶端需要經(jīng)過三個步驟:搜索設(shè)備、搜索服務(wù)和連接通信。服務(wù)發(fā)現(xiàn)API包括DataElement類、Discoverylistener接口、DiscoveryAgent類和ServiceRecord接口。
首先通過LocaIDevice取得DiscoveryAgent 對象。利用該對象發(fā)起一次設(shè)備查詢,設(shè)備找到后會調(diào)用DiscoveryListener接口對應(yīng)的方法,記錄下遠端設(shè)備RemoteDevice。再次通過DiscoveryAgent 對象,并提供剛剛找到的遠端設(shè)備,發(fā)起一次服務(wù)查詢來查詢感興趣的遠端服務(wù)。服務(wù)找到后會調(diào)用DiscoveryListener接口對應(yīng)的方法,將ServiceRecord服務(wù)記錄下來。至此,一次完整的搜索結(jié)束,得到了感興趣的ServiceRecord列表。
示例代碼如下:
try {
con=(StreamConnection)Connector.open(url);//打開連接
remoteDevice=RemoteDevice.getRemoteDevice(con);//取得遠端設(shè)備
remoteBTAddress=remoteDevice.getBluetoothAddress();//取得遠端設(shè)備藍牙地址
remoteBTName=remoteDevice.getFriendlyName(false);//取得遠端設(shè)備名稱
}
catch(Exception e){…} ;//異常處理
2)消費服務(wù):通過ServiceRecord的相應(yīng)方法可以取得遠端服務(wù)的URL。這樣就可根據(jù)服務(wù)的類型選擇創(chuàng)建對應(yīng)SPP 的StreamConnection 或?qū)?yīng)L2CAP 的L2CAPConnection來進行數(shù)據(jù)通信了。
2.4 藍牙連接
藍牙支持RFCOMM和L2CAP兩種類型的連接。藍牙API使用通用連接框架的StreamConnection和 StreamConnectionNotifier支持RFCOMM,連接類型L2CAPConnection和 L2CAPConnectionNotifier用于支持L2CAP。創(chuàng)建連接需要使用Connection.open(String urlName)方法,參數(shù)urlName代表了連接的URL,格式如下所示:
sheme://host:port;parameters
其中scheme 代表了連接的類型,對應(yīng)RFCOOM為btspp,對應(yīng)L2CAP為btl2cap。
host對應(yīng)服務(wù)端為localhost,對應(yīng)客戶端為遠端藍牙地址。
port對應(yīng)服務(wù)端為UUID,對應(yīng)客戶端為服務(wù)端口。
parameters 指定了可選的設(shè)置,如服務(wù)名稱或MTU大小。
使用服務(wù)端連接時,首先通過L2CAPConnectionNotifier或StreamConnectionNotifier建立連接,同時創(chuàng)建一個藍牙服務(wù)。
L2CAPConnectionNotifier notifier = (L2CAPConnectionNotifier) Connector.open(url);
然后調(diào)用acceptAndOpen()方法,該方法會自動將服務(wù)注冊到藍牙發(fā)現(xiàn)數(shù)據(jù)庫SDDB中,之后就可以被客戶端搜索了。
L2CAPConnection con = notifier.acceptAndOpen();
使用客戶端連接時,也是通過Connector.open(url)建立連接,參數(shù)url通過serviceRecord.getConnectionURL()取得,例如:
String url = serviceRecord.getConnectionURL(int requiredSecurity,boolean mustBeMaster);
L2CAPConnection con=(L2CAPConnection)Connector.open (url);
3 結(jié)束語
藍牙技術(shù)擁有連接簡單、互操作性強的特點,在無線辦公、電子支付、汽車工業(yè)、信息家電、醫(yī)療設(shè)備等領(lǐng)域中有著廣泛的應(yīng)用?;贘ava的JSR82規(guī)范開發(fā)無線藍牙應(yīng)用程序,繼承了Java語言優(yōu)秀的平臺無關(guān)特性,可以大大增加程序的可移植性。
參考文獻:
[1] 詹建飛.J2ME開發(fā)精解[M].北京:電子工業(yè)出版社,2006.
[2] 詹建飛.JavaME核心技術(shù)與最佳實踐[M].北京:電子工業(yè)出版社,2007.
[3] 馬毅華,馮恩信.基于JSR-82規(guī)范的J2ME藍牙應(yīng)用及其實現(xiàn)[J].工程應(yīng)用,2004,(8).