作者: 俞伟
搜索服务
搜索一个 指定的 服务 需指 定 UUI D 组, UUI D 定义了 连接方式 ,和服 务 ID 。 U UID 组包 括两 个标识, 第一个 标识表 示连接方 式,比 如:
连接方式 | UUID 值 | 位数 |
SDP | 0 x0 0 0 1 | 16 -b it |
RFCOM M | 0 x0 0 0 3 | 16 -b it |
OBEX | 0 x0 0 0 8 | 16 -b it |
L2 CA P | 0 x0 1 0 0 | 16 -b it |
Seri al P o rt | 0 x1 1 0 1 | 16 -b it |
第二个标 识表示 服务 I D , 这是蓝牙 客户端 与服务端 共同定义 好的服 务唯一识 别 ,可以 是
16 -b it, 3 2 -b it, 1 2 8 -b it 。
D isc o v ery Ag ent.s earchS er v ices( in t[] at trSet, UUI D [] uu id Set, Re m o te D e v ic e b t D e v , D isc o v ery L isten er li st ener ) ,该 API 启 动服务 搜索, uu id Set 定义寻找 的服务 , b tD e v 是蓝 牙 服务端, li s te n er 是 D is co v er yL ist ener 为 服务搜索 提供的回 调操作 。 函数 se arch Servic es( ) 在 每一个发 现的蓝 牙设备上 寻找目标 服务。 D isc o v ery Ag ent 可以同 时在多 个蓝 牙设备上 查找 服务, m axSer v ic eSearche s 定义本地 设备最 多可以 发起的服 务查找 。 当查找 没有结束 时, 函数 sear chS erv i ces() 让主 线程进入 等待, 当服务查 询结束 再 继续运 行。
private boolean searchServices(Vector devList) {
UUID[] searchList = new UUID[2];
searchList[0] = new UUID(0x0003);
searchList[1] = new UUID( "cccccccccccccccccccccccccccccccc" ,
false );
for ( int i = 0; i < devList.size(); i++) {
try {
agent .searchServices( null , searchList, (RemoteDevice)
devList.elementAt(i), this );
} catch (BluetoothStateException e) {}
synchronized ( bluelock ) {
serviceSearchCount ++;
if ( serviceSearchCount == maxServiceSearches ) {
try {
bluelock .wait();
} catch (Exception e) {}
}
}
}
while ( serviceSearchCount > 0) {
synchronized ( bluelock ) {
try {
bluelock .wait();
} catch (Exception e) {
}
}
}
return record != null ;
}
serv ic esD i sco v e red(in t tran sID, Ser v ic eRe c o rd [] se rvRe co rd ) 和 ser v iceSea rch Comp lete d (in t
tran sID, in t respC o d e) 为 D i sco v er yL ist ener 提 供的服 务搜索回 调接口 。 当在蓝 牙服务端 上找 到指定的 服务, s erv i ces D i sco v ered( ) 被调 用收入找 到的服务 。当在 一个蓝牙 服务端搜 索服 务完毕, s erv i ceSear chCo m p let ed() 会 被调用 。
public void serviceSearchCompleted( int transID, int respCode) {
serviceSearchCount --; synchronized ( bluelock ) { bluelock .notify();
}
}
public void servicesDiscovered( int transID, ServiceRecord[] servRecord) {
record = servRecord[0];
}
获取连接 UR L
获取服务 S erv ic eRe co rd 之后,调 用 Ser v iceR ec o rd .g et Co nn ec tio n U RL (in t, bo o lean ) 获 取连接
URL 。
public void getBluetoothUrl() throws Exception {
record = findService();
url = record .getConnectionURL(ServiceRecord. NOAUTHENTICATE_NOENCRYPT ,
false );
}
建立连接
获取连接 URL 之后,建 立 Strea m C o nn ect i o n 连接 。从连接 实例获 取输入流 和输出流 进行数 据交互。
public void connect() throws Exception {
streamConnection = (StreamConnection) Connector. open ( url );
dos = streamConnection .openDataOutputStream();
dis = streamConnection .openDataInputStream();
}
客户 端三种 蓝牙连 接方 式
S PP 连接方式
SPP 连 接方式 通过 Str ea m Co nn ect i o n 进行 连接, UR L 格式如 下: b tspp : / / [b lu et o o th add ress ]: [p o rt] b tspp : / / 0 00 a 9 5 0 2 0 c 7 b : 5; n am e =SP P ex
public void runSPPConnection (){
try {
StreamConnection connection = null ; DataOutputStream os = null ; DataInputStream is = null ;
try {
// 创建 St re am Co nn ec ti on
connection = (StreamConnection) Connector. open ( _url );
// 打开输入 流读取数 据
String message = "/nJSR-82 CLIENT says hello!" ; os = connection.openDataOutputStream(); os.write(message.getBytes());
os.flush();
// 打开输出 流发送数 据
is = connection.openDataInputStream();
byte [] buffer = new byte [ 1024 ];
int readBytes = is.read(buffer);
String receivedMessage = new String(buffer, 0, readBytes);
}
finally {
os.close(); is.close(); connection.close();
}
}
catch (IOException ioe){
BluetoothJSR82Demo. errorDialog (ioe.toString());
}
}
L2 C APC onne c t i o n 连接方式
L2 CA P 连接 URL 格 式如下 :
bt l 2cap:/ / [ B l u e t oo t h Ad d r e ss ] :[po r t];n am e =[n am e t e xt]
bt l 2cap:/ / 00 0a 95 02 0c7b: 5;n am e =sy n c l 2cap
public void runL2CAPConnection (){
try {
L2CAPConnection connection = null ;
try {
// 打开 L2 CAP 连接
connection = (L2CAPConnection) Connector. open ( _url );
// 想服务 端发送数 据
String message = "/n[CLIENT] JSR -82 CLIENT says hello!" ;
connection.send(message.getBytes());
// 读取服 务端数据
byte [] buffer = new byte [ 1024 ];
int readBytes = connection.receive(buffer);
String receivedMessage = new String(buffer, 0, readBytes);
}
finally {
connection.close();
}
}
catch (IOException ioe){
BluetoothJSR82Demo. errorDialog (ioe.toString());
}
}
OBE X 连接方式
OBEX 连 接 UR L 格式 如下 :
"tcpob e x:// li t e spee d: 65 12 "
"btg oe p:// 00 0a 95 02 0c7 b: 99 6"
"i r d ao b e x://d i sco v e r .08 ; i as=fax "
public void runOBEX Connection()
{
try {
Connection connection = null ; OutputStream outputStream = null ; Operation putOperation = null ; ClientSession cs = null ;
try {
// 打开连接 , 获取 ClientSession
connection = Connector. open ( _url ); cs = (ClientSession) connection; cs.connect( null );
// 设置 He ad er Se t 并填充数 据
byte filebytes[] = "[CLIENT] Hello.." .getBytes();
HeaderSet hs = cs.createHeaderSet(); hs.setHeader(HeaderSet. NAME , "test.txt" ); hs.setHeader(Header Set. TYPE , "text/plain" ); hs.setHeader(HeaderSet. LENGTH , new Long(filebytes. length ));
// 从 Cl ie nt S es si on 中获取 Operation putOperation = cs.put(hs);
// 从 Op er at i on 获取输出 流,发 送数据
outputStream = putOperation.openOutputStream();
outputStream.write(filebytes);
}
finally {
outputStream.close(); putOperation.close(); cs.disconnect( null ); connection.close( );
}
}
catch (Exception e)
{
BluetoothJSR82Demo. errorDialog (e.toString());
}
}
BlackBerry SDK下载