?? bluetoothdiscovery.java
字號(hào):
package game.bluetooth;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
import java.util.Vector;
import javax.bluetooth.*;
import java.util.Timer;
import java.util.TimerTask;
/**
* BluetoothDiscoery類提供了易用的API用來搜索設(shè)備與服務(wù)
* 主要的方法是searchService和waitOnConnection
* searchService方法用來搜索鄰近的藍(lán)牙設(shè)備并且與提供對(duì)應(yīng)服務(wù)的設(shè)備建立連接
* waitOnConnection方法則是用來提供服務(wù)并且等待其它設(shè)備與本地設(shè)備建立連接
* 在這兩個(gè)方法使用前,讀者應(yīng)該提供備用戶名和服務(wù),這里有兩個(gè)方法:setName和setServiceUUID方法來設(shè)置
* 這里使用LIAC(有限查詢)服務(wù)模式,
*/
public class BluetoothDiscovery
extends Alert
implements CommandListener
{
static int dev_num = 0;//用來判斷設(shè)備發(fā)現(xiàn)只調(diào)用一次,可發(fā)現(xiàn)多個(gè),結(jié)果為真
// Attribute ID for service name for base language
static private final int SERVICE_NAME_BASE_LANGUAGE = 0x0100;
// 指定查找設(shè)備為手機(jī),0x0200是手機(jī)在藍(lán)牙通訊中指定的特征碼
static private final int MAJOR_DEVICE_CLASS_PHONE = 0x0200;
//四種服務(wù)發(fā)現(xiàn)類型,本例程中只使用了一種:SEARCH_ALL_DEVICES_SELECT_ONE
static public final int SEARCH_CONNECT_FIRST_FOUND = 1;
static public final int SEARCH_CONNECT_ALL_FOUND = 2;
static public final int SEARCH_ALL_DEVICES_SELECT_ONE = 3;
static public final int SEARCH_ALL_DEVICES_SELECT_SEVERAL = 4;
// 一臺(tái)Master能夠連接的最大藍(lán)牙設(shè)備數(shù)
static private final int BLUETOOTH_MAX_DEVICES = 7;
// MainMIDlet傳入的display對(duì)象
private Display display;
//本地設(shè)備的引用
private LocalDevice localDevice = null;
//用來保存發(fā)現(xiàn)模式的變量
private int previousDiscoverabilityMode = -1;
private String serviceUUID = null;
private String localName = null;
//服務(wù)代理和Discovery監(jiān)聽器,用來發(fā)現(xiàn)設(shè)備與服務(wù)用
private DiscoveryAgent discoveryAgent;
private Listener listener;
//發(fā)現(xiàn)模式
private int searchType;
// trans action id for current service search, if there is no serv search this is -1
private int serviceSearchTransId;
//返回服務(wù)的url字符串向量,可用來建立連接
private Vector urlStrings;
//所有發(fā)現(xiàn)的服務(wù)記錄向量
private Vector foundServiceRecords;
private int maxDevices;
//一個(gè)顯示所有己連接設(shè)備的列表
private DeviceList deviceList;
//警告字符串,如沒有設(shè)備或服務(wù)被發(fā)現(xiàn)時(shí)通知玩家
private String warning;
// notifier建立服務(wù)時(shí)使用
private StreamConnectionNotifier notifier;
// 建立連接的對(duì)象數(shù)組
private BluetoothConnection[] btConnections;
// 代表BluetoothDiscovery本身,方便內(nèi)部類訪問
private BluetoothDiscovery root;
// 進(jìn)度條對(duì)象的引用
private InqProgressBar progressBar;
private Object block_m; // Master端的線程同步對(duì)象
private Object block_s; // Slave端的線程同步對(duì)象
private Object block_ss; // 服務(wù)查找時(shí)的阻塞線程
private Object block_notifier; //
/**
* BluetoothDiscovery類的構(gòu)造方法,
* disp是Display類的實(shí)例,
* 因?yàn)橥婕倚枰ㄟ^BluetoothDiscovery的內(nèi)部類與Display的交互了解服務(wù)發(fā)現(xiàn)狀態(tài)
*
*/
public BluetoothDiscovery( Display disp )
{
super( "" );
root = this;
display = disp;
// Initialize
progressBar = null;
deviceList = null;
// 構(gòu)造block_m、block_s、block_ss、block_notifier對(duì)象來進(jìn)行本地設(shè)備與遠(yuǎn)端設(shè)備的同步
block_m = new Object();
block_s = new Object();
block_ss = new Object();
block_notifier = new Object();
try
{
// 獲得本地設(shè)備
localDevice = LocalDevice.getLocalDevice();
// 得到本地設(shè)備最大可連接遠(yuǎn)端設(shè)備數(shù)
maxDevices = Integer.parseInt( localDevice.getProperty( "bluetooth.connected.devices.max" ) );
if( maxDevices > BLUETOOTH_MAX_DEVICES )
{ // 最多可連接數(shù)為7
// BLUETOOTH_MAX_DEVICES=7
maxDevices = BLUETOOTH_MAX_DEVICES;
}
}
catch(Exception e)
{
localDevice = null;
}
}
private void closeNotifier()
{
synchronized( block_notifier )
{
if( notifier != null )
{
try
{
notifier.close();
}
catch(Exception e)
{
String message = "Error trying to close notifier" +
e.getMessage();
ErrorScreen.showError(message, display.getCurrent());
}
notifier = null;
}
}
}
public void commandAction(Command c, Displayable s)
{
switch( c.getCommandType() )
{
case Command.CANCEL:
try
{
if( listener != null )
{
// 通知用戶取消搜索
Alert a = new Alert( "", "Search cancelled", null, AlertType.INFO );
a.setTimeout( 10000 );
display.setCurrent( a );
// 取消搜索
discoveryAgent.cancelInquiry( listener );
// 取消服務(wù)搜索
// 取消服務(wù)搜索需要使用一個(gè)新的線程來結(jié)束
// 不然的話上面的Alert畫面就不會(huì)顯示出來
waitOnServSearchTermination w = new waitOnServSearchTermination();
w.start();
}
listener = null;
closeNotifier();
// 停止progressBar
if( progressBar != null )
{
progressBar.stop();
progressBar = null;
}
}
catch(Exception e)
{
String message = "Error trying to cancel: " +
e.getMessage();
ErrorScreen.showError(message, display.getCurrent());
}
break;
}//end switch
}
/**
* 保存發(fā)現(xiàn)模式,用來以后的模式恢復(fù)
*/
private void saveDiscoverability()
{
try
{
previousDiscoverabilityMode =
LocalDevice.getLocalDevice().getDiscoverable();
}
catch(Exception e)
{ }
}
/**
* 重新設(shè)置發(fā)現(xiàn)模式,把以前保存的模式設(shè)置為當(dāng)前發(fā)現(xiàn)模式
*/
private void restoreDiscoverability()
{
try
{
if( previousDiscoverabilityMode != -1 )
{
localDevice.setDiscoverable( previousDiscoverabilityMode );
}
}
catch( Exception e )
{ }
}
/**
* 設(shè)置代表本地玩家的用戶名
*/
public void setName( String ln )
{
localName = ln;
}
/**
* 設(shè)置UUID值
*/
public void setServiceUUID( String UUID )
{
serviceUUID = UUID;
}
public BluetoothConnection[] searchService( int st )
throws BluetoothStateException, InterruptedException, IOException
{
StreamConnection con;
DataElement de;
String rname;
// serviceSearchTransId為服務(wù)搜索號(hào)(transID)
serviceSearchTransId = -1;
searchType = st;
foundServiceRecords = new Vector();
urlStrings = new Vector();
// 得到服務(wù)代理類對(duì)象,進(jìn)行設(shè)備與服務(wù)的發(fā)現(xiàn)
discoveryAgent = localDevice.getDiscoveryAgent();
// 構(gòu)造Discovery監(jiān)聽器對(duì)象
listener = new Listener();
// 顯示搜索進(jìn)度條
progressBar = new InqProgressBar( "Search Devices...", 105 );
warning = "";
// 異步調(diào)用設(shè)備發(fā)現(xiàn)(startInquiry)方法,這里使用block_m對(duì)象進(jìn)行線程阻塞
synchronized( block_m )
{
discoveryAgent.startInquiry( DiscoveryAgent.LIAC, listener );
block_m.wait();
}
deviceList = null;
if( progressBar != null )
{
progressBar.stop();
}
if( ! warning.equals( "" ) )
{
Alert al = new Alert( null, warning, null, AlertType.INFO );
al.setTimeout( 2000 );
display.setCurrent( al );
synchronized( al )
{
try
{
al.wait( 2000 );
}
catch(InterruptedException e )
{ }
}
}
// 構(gòu)造一個(gè)列表
btConnections = new BluetoothConnection[urlStrings.size()];
// 判斷是否有設(shè)備被發(fā)現(xiàn),如發(fā)現(xiàn),進(jìn)行下一步操作
if( urlStrings.size() > 0 )
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -