📄 bluetoothdiscovery.java
字号:
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用来搜索设备与服务
* 主要的方法是searchService和waitOnConnection
* searchService方法用来搜索邻近的蓝牙设备并且与提供对应服务的设备建立连接
* waitOnConnection方法则是用来提供服务并且等待其它设备与本地设备建立连接
* 在这两个方法使用前,读者应该提供备用户名和服务,这里有两个方法:setName和setServiceUUID方法来设置
* 这里使用LIAC(有限查询)服务模式,
*/
public class BluetoothDiscovery
extends Alert
implements CommandListener
{
static int dev_num = 0;//用来判断设备发现只调用一次,可发现多个,结果为真
// Attribute ID for service name for base language
static private final int SERVICE_NAME_BASE_LANGUAGE = 0x0100;
// 指定查找设备为手机,0x0200是手机在蓝牙通讯中指定的特征码
static private final int MAJOR_DEVICE_CLASS_PHONE = 0x0200;
//四种服务发现类型,本例程中只使用了一种: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;
// 一台Master能够连接的最大蓝牙设备数
static private final int BLUETOOTH_MAX_DEVICES = 7;
// MainMIDlet传入的display对象
private Display display;
//本地设备的引用
private LocalDevice localDevice = null;
//用来保存发现模式的变量
private int previousDiscoverabilityMode = -1;
private String serviceUUID = null;
private String localName = null;
//服务代理和Discovery监听器,用来发现设备与服务用
private DiscoveryAgent discoveryAgent;
private Listener listener;
//发现模式
private int searchType;
// trans action id for current service search, if there is no serv search this is -1
private int serviceSearchTransId;
//返回服务的url字符串向量,可用来建立连接
private Vector urlStrings;
//所有发现的服务记录向量
private Vector foundServiceRecords;
private int maxDevices;
//一个显示所有己连接设备的列表
private DeviceList deviceList;
//警告字符串,如没有设备或服务被发现时通知玩家
private String warning;
// notifier建立服务时使用
private StreamConnectionNotifier notifier;
// 建立连接的对象数组
private BluetoothConnection[] btConnections;
// 代表BluetoothDiscovery本身,方便内部类访问
private BluetoothDiscovery root;
// 进度条对象的引用
private InqProgressBar progressBar;
private Object block_m; // Master端的线程同步对象
private Object block_s; // Slave端的线程同步对象
private Object block_ss; // 服务查找时的阻塞线程
private Object block_notifier; //
/**
* BluetoothDiscovery类的构造方法,
* disp是Display类的实例,
* 因为玩家需要通过BluetoothDiscovery的内部类与Display的交互了解服务发现状态
*
*/
public BluetoothDiscovery( Display disp )
{
super( "" );
root = this;
display = disp;
// Initialize
progressBar = null;
deviceList = null;
// 构造block_m、block_s、block_ss、block_notifier对象来进行本地设备与远端设备的同步
block_m = new Object();
block_s = new Object();
block_ss = new Object();
block_notifier = new Object();
try
{
// 获得本地设备
localDevice = LocalDevice.getLocalDevice();
// 得到本地设备最大可连接远端设备数
maxDevices = Integer.parseInt( localDevice.getProperty( "bluetooth.connected.devices.max" ) );
if( maxDevices > BLUETOOTH_MAX_DEVICES )
{ // 最多可连接数为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 );
// 取消服务搜索
// 取消服务搜索需要使用一个新的线程来结束
// 不然的话上面的Alert画面就不会显示出来
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
}
/**
* 保存发现模式,用来以后的模式恢复
*/
private void saveDiscoverability()
{
try
{
previousDiscoverabilityMode =
LocalDevice.getLocalDevice().getDiscoverable();
}
catch(Exception e)
{ }
}
/**
* 重新设置发现模式,把以前保存的模式设置为当前发现模式
*/
private void restoreDiscoverability()
{
try
{
if( previousDiscoverabilityMode != -1 )
{
localDevice.setDiscoverable( previousDiscoverabilityMode );
}
}
catch( Exception e )
{ }
}
/**
* 设置代表本地玩家的用户名
*/
public void setName( String ln )
{
localName = ln;
}
/**
* 设置UUID值
*/
public void setServiceUUID( String UUID )
{
serviceUUID = UUID;
}
public BluetoothConnection[] searchService( int st )
throws BluetoothStateException, InterruptedException, IOException
{
StreamConnection con;
DataElement de;
String rname;
// serviceSearchTransId为服务搜索号(transID)
serviceSearchTransId = -1;
searchType = st;
foundServiceRecords = new Vector();
urlStrings = new Vector();
// 得到服务代理类对象,进行设备与服务的发现
discoveryAgent = localDevice.getDiscoveryAgent();
// 构造Discovery监听器对象
listener = new Listener();
// 显示搜索进度条
progressBar = new InqProgressBar( "Search Devices...", 105 );
warning = "";
// 异步调用设备发现(startInquiry)方法,这里使用block_m对象进行线程阻塞
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 )
{ }
}
}
// 构造一个列表
btConnections = new BluetoothConnection[urlStrings.size()];
// 判断是否有设备被发现,如发现,进行下一步操作
if( urlStrings.size() > 0 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -