📄 bluetoothdiscovery.java
字号:
progressBar = new PageProgressBar( "Connecting...", urlStrings.size() );
// 连接查询到的设备(这里只有一个设备会被返回)
for( int i=0; i<urlStrings.size(); i++ )
{
de = ((ServiceRecord)foundServiceRecords.elementAt(i)).getAttributeValue( SERVICE_NAME_BASE_LANGUAGE );
rname = (String) de.getValue();
((PageProgressBar)progressBar).nextDevice();
btConnections[i] = new BluetoothConnection( (String) urlStrings.elementAt(i), localName, rname );
// 向远端玩家发送设置的代表自己的名称字符串
btConnections[i].writeString( localName );
}
progressBar.stop();
}
// 释放progressBar
progressBar = null;
// 释放listener
listener = null;
return btConnections;
}
/**
* 使本地设备向外发布自身的服务,并且等待连接
* 返回一个BluetoothConnection数组
*/
public BluetoothConnection[] waitOnConnection()
throws BluetoothStateException, IOException, InterruptedException
{
acceptAndOpenThread t;
String ServiceName;
// 保存当前发现状态
saveDiscoverability();
// 设置为有限查询状态
localDevice.setDiscoverable( DiscoveryAgent.LIAC );
// 调用Connector的open方法返回一个StreamCOnnectionNotifier对象
notifier = (StreamConnectionNotifier) Connector.open( "btspp://localhost:" + serviceUUID + ";name=" + localName + ";authorize=false;authenticate=false;encrypt=false" );
// 调用Alert的方法
setTitle( "Waiting" );
setString( "Waiting for someone to connect..." );
setTimeout( FOREVER );
addCommand( new Command( "Cancel", Command.CANCEL, 1 ) );
setCommandListener( this );
display.setCurrent( this );
// 设立一个新的acceptAndOpenThread线程来等待Master端的连接
t = new acceptAndOpenThread();
// 阻塞,直到被唤醒
synchronized( block_s )
{
// 运行acceptAndOpenThread线程
t.start();
// 这里使用block_s对象进行阻塞
block_s.wait();
}
notifier = null;
restoreDiscoverability();
return btConnections;
}
// 内部类,封装了一个gauge进度条控件
private class InqProgressBar
extends TimerTask
{
protected Gauge gauge;
protected Timer tm;
private InqProgressBar( String title, int max )
{
gauge = new Gauge( title, false, max, 0 );
Command cmStop = new Command( "Cancel", Command.CANCEL, 1 );
// 创建一个Form对象,将gauge、stop commmand加在其上
Form f = new Form("");
f.append( gauge );
f.addCommand( cmStop );
f.setCommandListener( root );
display.setCurrent( f );
tm = new Timer();
tm.scheduleAtFixedRate( this, 0, 100);
}
public void run()
{
int time;
time = gauge.getValue() + 1;
if( time > gauge.getMaxValue() )
{
time = 0;
}
gauge.setValue( time );
}
protected void stop()
{
cancel();
tm.cancel();
}
}
// 内部类
// 继承自InqProgressBar
private class PageProgressBar
extends InqProgressBar
{
static final int PAGE_TIME = 30; // in 1/10 secs, 3 secs
private int timer_max;
private PageProgressBar( String str, int countDev )
{
super( str, countDev*PAGE_TIME );
timer_max = 0;
}
public final void run()
{
int time;
// add one second
time = gauge.getValue() + 1;
// Is current value of gauge less than the max?
if( time > timer_max )
{ // Stop
time = timer_max;
}
// Store new value
gauge.setValue( time );
}
/**
* Start progress bar for next device.
*/
public void nextDevice()
{
// Set current value
gauge.setValue( timer_max );
// Stop the timer
timer_max += PAGE_TIME;
}
}
// 内部类,实现了DiscoveryListener接口,实现了该接口定义的方法
// deviceDiscovered,inquiryCompleted,servicesDiscovered,serviceSearchCompleted
//
private class Listener
implements DiscoveryListener
{
private Vector cached_devices;
ServiceRecord currServRec;
/** 构造方法
*/
public Listener()
{
cached_devices = new Vector();
}
/**
* devoceDiscovered方法在设备被发现时调用,由DiscoveryAgent的startInquiry方法
* 需要注意的是一个设备可能被发现多次,
* 因此需要进行检验,不能重复记录
* discoveryAgent.startInquiry( DiscoveryAgent.LIAC, listener );
* btDevice :设备搜索中被发现的设备
* cod :设备类,通过调用getMajorDeviceClass()方法判断所发现的设备是否是手机
*/
public void deviceDiscovered( RemoteDevice btDevice, DeviceClass cod )
{
if( cod.getMajorDeviceClass() != MAJOR_DEVICE_CLASS_PHONE )
{
return;
}
dev_num++;
//需要进行判断,看是否是新发现的设备,如果,则加入cached_devices向量中
if( ! cached_devices.contains( btDevice ) )
{
cached_devices.addElement( btDevice );
}
}
/**
* inquiryCompleted方法在搜索邻近设备结束后调用
* discType属以下中的一个:
* 1:INQUIRY_COMPLETED:搜索正常结束时返回
* 2:INQUIRY_TERMINATED:搜索被DiscoveryAgent.cancelInquiry()方法取消
* 3:INQUIRY_ERROR:搜索过程中发生错误
*/
public void inquiryCompleted( int discType )
{
// 搜索设备正常结束
if( discType == INQUIRY_COMPLETED )
{
if( cached_devices.size() == 0 )
{
warning = "No devices found!";
}
else
{
// 结束设备搜索进度条
progressBar.stop();
// 开始服务搜索进度条
progressBar = new PageProgressBar( "Search Service...", cached_devices.size() );
// 开始搜索服务
nextDeviceServiceSearch();
//返回
return;
}
}
// 如果搜索被中断或没有设备被发现,则直接唤醒线程,searchService继续向下运行
synchronized( block_m )
{
block_m.notifyAll();
}
}
/**
* NextDeviceServiceSearch.
* 该方法用来从一个设备中查找是否有相关服务
*/
private void nextDeviceServiceSearch()
{
UUID[] u = new UUID[1];
u[0] = new UUID( serviceUUID, false );
int attrbs[] =
{ SERVICE_NAME_BASE_LANGUAGE };
RemoteDevice dev;
((PageProgressBar)progressBar).nextDevice();
// 获得下一设备
try
{
dev = (RemoteDevice) cached_devices.firstElement();
cached_devices.removeElementAt( 0 );
}
catch( Exception e )
{
// 所有设备都已经搜索
if( foundServiceRecords.size() == 0 )
{
// 没有感兴趣的服务被发现
warning = "No service found!";
}
if( (foundServiceRecords.size() == 0)
| (searchType == SEARCH_CONNECT_ALL_FOUND) )
{
synchronized( block_m )
{
block_m.notifyAll();
}
}
if( deviceList != null )
{
deviceList.ready();
}
return;
}// end catch
// 搜索服务
try
{
currServRec = null;
//这里,使用DiscoveryAgent的searchServices方法,在指定的设备上搜索服务,
//服务被发现的话,则listener类的相应监听方法被回调
//static private final int SERVICE_NAME_BASE_LANGUAGE = 0x0100;
//int attrbs[] = { SERVICE_NAME_BASE_LANGUAGE };
serviceSearchTransId = discoveryAgent.searchServices( attrbs, u, dev, listener );
}
catch( BluetoothStateException e )
{
// 发生错误,
// 搜索下一设备
nextDeviceServiceSearch();
}
}
/**
* 如指定的服务被发现,则该方法被调用
* @param transID: the transaction ID of the service search that is posting the result.
* @param servRecord: 指的是所要搜索的服务
*/
public void servicesDiscovered( int transID, ServiceRecord[] servRecord )
{
// 在指定设备上发现的服务
currServRec = servRecord[0];
}
/**
* searchServices
* transID:代表服务搜索号
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -