蓝牙开发之从手机走向PC【2】——手机与手机之间的通信实现
2010-02-04 00:00:00 来源:WEB开发网在该文件中需要解释下的是SERVER_UUID,这个是全球用户唯一标示符,在蓝牙服务中我们服务器端其实就是将带有这一唯一标识的服务发布出去,而客户端则是根据这个UUID来在设备中搜索这一服务的。其分为长短标识,短标识说明采用的链接协议,长标识则代表服务的标识。其他的笔者都有比较详细的注释,这儿不再赘述。
bluetooth包中的BlueClientService.java文件:
/**
* 实现客户端蓝牙服务的类
* @author royen
* @since 2010.1.24
*/
public class BlueClientService implements Runnable,DiscoveryListener{
//目标服务标识
private final static UUID TARGET_UUID=new UUID("F0E0D0C0B0A000908070605040302010",false);
//存储发现的设备和服务的集合
private Vector devices=new Vector();
private Vector records=new Vector();
//存储服务属性的集合
private UUID[] uuidSet=null;
//蓝牙发现代理类
private DiscoveryAgent discoveryAgent=null;
//客户端界面
private BlueClient clientForm;
//服务搜索的事务id集合
private int[] transIDs;
//存活的服务索引
private int activeIndex=-1;
public BlueClientService(BlueClient frm){
this.clientForm=frm;
}
public synchronized void run() {
//发现设备和服务的过程中,给用户以Gauge
Gauge g=new Gauge(null,false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING);
clientForm.append(g);
//如果初始化失败
if(!initLocalDevice()){
clientForm.appendInfo("bluetooth init failed~");
return;
}
//生成服务和属性的全球唯一标示符
uuidSet=new UUID[2];
uuidSet[0]=new UUID(0x1101); //0x1101表示 采用btspp协议
uuidSet[1]=TARGET_UUID; //目标服务标示
try{
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
}
catch(Exception ex){
clientForm.appendInfo(ex.getMessage());
return;
}
try{
//阻塞,由inquiryCompleted函数回调唤醒
wait();
}
catch(InterruptedException ex){
clientForm.appendInfo(ex.getMessage());
return;
}
//添加显示信息
clientForm.appendInfo("search device completed,find "+devices.size()+" devices~");
clientForm.appendInfo("now begin to search service...");
transIDs=new int[devices.size()];
//遍历开启目标服务的蓝牙设备
for(int i=0;i<devices.size(); i++ ){
RemoteDevice rd=(RemoteDevice)devices.elementAt(i);
try{
//记录每一次服务搜索的事务ID
transIDs[i]=discoveryAgent.searchServices(null, uuidSet, rd, this);
}
catch(BluetoothStateException ex){
continue;
}
}
try{
//阻塞,由serviceSearchCompleted函数回调唤醒
wait();
}
catch(InterruptedException ex){
clientForm.appendInfo(ex.getMessage());
return;
}
//添加显示信息
clientForm.appendInfo("service search finished~,find "+records.size()+" services");
if(records.size()>0){
//搜索到服务,改变客户端界面
clientForm.changeForm();
}
//获取存活的服务索引
activeIndex=getActiveService();
}
/**
* 获取存活的服务索引
* @return
*/
private int getActiveService(){
for(int i=0;i<records.size();i++){
ServiceRecord sr=(ServiceRecord)records.elementAt(i);
if(accessService(sr,"connect...")){
return i;
}
}
return -1;
}
/**
* 发送信息到服务器
* @param msg
*/
public void sendMsg(String msg){
accessService((ServiceRecord)records.elementAt(activeIndex),msg);
}
/**
* 访问指定的服务
* @param sr
* @return
*/
private boolean accessService(ServiceRecord sr,String msg){
boolean result=false;
try {
String url = sr.getConnectionURL(
ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
StreamConnection conn = (StreamConnection) Connector.open(url);
DataOutputStream dos=conn.openDataOutputStream();
dos.writeUTF(msg);
dos.close();
DataInputStream dis=conn.openDataInputStream();
String echo=dis.readUTF();
dis.close();
clientForm.appendInfo("echo from server:"+echo);
result=true;
}
catch (IOException e) {
System.out.println("exception here");
}
return result;
}
/**
* 初始化本地蓝牙设备
* @return
*/
private boolean initLocalDevice(){
boolean isReady=false;
try{
LocalDevice localDevice=LocalDevice.getLocalDevice();
discoveryAgent=localDevice.getDiscoveryAgent();
//设置自身设备不可访问性
localDevice.setDiscoverable(DiscoveryAgent.NOT_DISCOVERABLE);
isReady=true;
}
catch(Exception ex){
isReady=false;
}
return isReady;
}
/**
* 设备发现
*/
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
if(devices.indexOf(btDevice)==-1){
devices.addElement(btDevice);
}
}
/**
* 搜索完毕
*/
public void inquiryCompleted(int disType){
synchronized(this){
notify();
}
}
/**
* 服务发现
*/
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
for(int i=0;i<servRecord.length;i++){
records.addElement(servRecord[i]);
}
}
/**
* 服务搜索完毕
*/
public void serviceSearchCompleted(int transID, int respCode) {
//遍历,并标志搜索到的服务
for(int i=0;i<transIDs.length;i++){
if(transIDs[i]==transID){
transIDs[i]=-1;
}
}
//如果对所有的设备的服务都搜索完毕
boolean finished=false;
for(int i=0;i<transIDs.length;i++){
if(transIDs[i]==-1){
finished=true;
break;
}
}
if(finished){
synchronized(this){
notify();
}
}
}
}
这个文件中需要解释的是BlueClientService类实现了DiscoveryListener接口,由于客户端需要进行周围蓝牙设备以及发布的服务搜索,所以必须实现DiscoveryListener接口的四个回调函数,分别为deviceDiscovered(搜索设备时候每发现一个设备时回调)、inquiryCompleted(搜索设备结束时回调)、servicesDiscovered(搜索服务时候回调)和 serviceSearchCompleted(服务搜索完毕的时候回调)。
更多精彩
赞助商链接