import java.io.IOException;
import java.util.Vector;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
/**
* 蓝牙设备搜索及服务搜索类<BR>
*
*
* @author Administrator
* @version V1.0
*/
public final class BlueTooth implements DiscoveryListener , Runnable
{
/**
* 准备
*/
public static final int STATUS_READY = 0x01;
/**
* 设备搜索中
*/
public static final int STATUS_DEV_SEARCHING = 0x02;
/**
* 设备搜索完成
*/
public static final int STATUS_DEV_SEARCH_FINISH = 0x03;
/**
* 设备搜索失败
*/
public static final int STATUS_DEV_SEARCH_ERROR = 0x04;
/**
* 服务搜索中
*/
public static final int STATUS_SER_SEARCHING = 0x10;
/**
* 服务搜索完成
*/
public static final int STATUS_SER_SEARCH_FINISH = 0x11;
/**
* 服务搜索失败
*/
public static final int STATUS_SER_SEARCH_ERROR = 0x12;
/**
* 创建与服务的连接中
*/
public static final int STATUS_CONNECTING = 0x20;
/**
* 创建服务连接成功
*/
public static final int STATUS_CONNECT_OK = 0x21;
/**
* 创建服务连接失败
*/
public static final int STATUS_CONNECT_FAIL = 0x22;
/**
* 单实例
*/
private static BlueTooth instance = new BlueTooth();
/**
* 本地设备
*/
protected LocalDevice localDevice;
/**
* 设备搜索代理
*/
protected DiscoveryAgent discoveryAgent;
/**
* 搜索到的设备列表
*/
protected Vector remoteDeviceVector = new Vector();
/**
* 搜索到的服务信息列表
*/
protected Vector serviceInfoVector = new Vector();
/**
* 搜索到的服务列表
*/
protected Vector serviceRecordVector = new Vector();
/**
*
*/
// protected int connectType = 0;
/**
* 状态
*/
protected int status = 0;
/**
* 是否支持蓝牙
*/
protected boolean supportJSR82 = false;
/**
* 对象锁,控制设备搜索和服务搜索
*/
private Object bluelock = new Object();
/**
* 过滤器
*/
private Filter filter;
/**
* 预设设备
*/
private String expectDevice;
/**
* 构造子
*/
private BlueTooth()
{
try
{
Class.forName("javax.bluetooth.LocalDevice");
supportJSR82 = true;
}
catch (Exception ex)
{
supportJSR82 = false;
}
try
{
// 获得本地设备
localDevice = LocalDevice.getLocalDevice();
// 获得本地设备代理
discoveryAgent = localDevice.getDiscoveryAgent();
}
catch (Exception e)
{
supportJSR82 = false;
}
}
/**
* 获取单实例
*
* @return 静态单实例
*/
public static BlueTooth getInstance()
{
return instance;
}
/**
* 搜索蓝牙设备
*
* @return 搜索到的蓝牙设备
*/
public Vector findDevices()
{
remoteDeviceVector.removeAllElements();
try
{
// 启动搜索代理发现设备并与DiscoveryListener注册回调
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
// 设备搜索状态
setStatus(STATUS_DEV_SEARCHING);
// 设备搜索过程是异步的,这里需要同步搜索过程
// 设备搜索完毕会通知主线程继续运行
synchronized (bluelock)
{
// 加上while,break纯粹是为了规避findbugs检查
while (status >= STATUS_READY && status < STATUS_DEV_SEARCH_FINISH)
{
try
{
bluelock.wait();
// break;
}
catch (Exception e)
{
break;
}
}
}
}
catch (BluetoothStateException e)
{
setStatus(STATUS_DEV_SEARCH_ERROR);
}
return remoteDeviceVector;
}
/**
* 获取手机匹配装置列表中的蓝牙设备集合
*
* @return 搜索到的蓝牙设备
*/
public Vector findDeviceInCache()
{
Vector vector = new Vector();
RemoteDevice[] rds = discoveryAgent.retrieveDevices(DiscoveryAgent.CACHED);
if (rds != null)
{
for (int i = 0; i < rds.length; i++)
{
vector.addElement(rds[i]);
}
}
rds = discoveryAgent.retrieveDevices(DiscoveryAgent.PREKNOWN);
if (rds != null)
{
for (int i = 0; i < rds.length; i++)
{
vector.addElement(rds[i]);
}
}
return vector;
}
/**
* 取消正在执行的设备搜索
*/
public void cancelFindDevices()
{
if (status == STATUS_DEV_SEARCHING)
{
discoveryAgent.cancelInquiry(this);
}
}
/**
* 蓝牙设备发现时的回调方法<BR>
* 每发现一个蓝牙装置,此方法将被调用一次。
*
* @param btDevice 搜索到的蓝牙装置
* @param cod 服务类,远程蓝牙装置的主设备类或附设备类
* @see javax.bluetooth.DiscoveryListener#deviceDiscovered(javax.bluetooth.RemoteDevice,
* javax.bluetooth.DeviceClass)
*/
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
{
if (filter != null && !filter.match(btDevice))
{
return;
}
else
{
remoteDeviceVector.addElement(btDevice);
}
if (expectDevice != null && expectDevice.equals(btDevice.getBluetoothAddress()))
{
discoveryAgent.cancelInquiry(this);
}
}
/**
* 设备搜索结束时的回调方法<BR>
*
*
* @param discType 搜索请求结束类型; 为INQUIRY_COMPLETED, INQUIRY_TERMINATED, 或INQUIRY_ERROR
* @see javax.bluetooth.DiscoveryListener#inquiryCompleted(int)
*/
public void inquiryCompleted(int discType)
{
if (discType == INQUIRY_COMPLETED)
{
setStatus(STATUS_DEV_SEARCH_FINISH);
}
else if (discType == INQUIRY_ERROR)
{
setStatus(STATUS_DEV_SEARCH_ERROR);
}
// 蓝牙搜索执行完毕,通知主线程继续
synchronized (bluelock)
{
bluelock.notifyAll();
}
}
/**
* 搜索蓝牙设备提供的服务
*
* @param device 远程蓝牙设备
* @param uuids 搜索服务UUID数组
* @return 搜索到的服务集合
*/
public Vector findServices(RemoteDevice device, UUID[] uuids)
{
serviceInfoVector.removeAllElements();
serviceRecordVector.removeAllElements();
try
{
discoveryAgent.searchServices(new int[] {0x100 }, uuids, device, this);
setStatus(STATUS_SER_SEARCHING);
}
catch (BluetoothStateException e)
{
setStatus(STATUS_SER_SEARCH_ERROR);
}
synchronized (bluelock)
{
// 加上while,break纯粹是为了规避findbugs检查
while (status > STATUS_DEV_SEARCHING && status <= STATUS_SER_SEARCHING)
{
try
{
bluelock.wait();
// break;
}
catch (InterruptedException e)
{
break;
}
}
}
return serviceRecordVector;
}
/**
* 搜索服务时找到服务的回调方法<BR>
* [功能详细描述]
*
* @param transID 服务搜索事务ID
* @param servRecord 搜索到的服务记录数组
* @see javax.bluetooth.DiscoveryListener#servicesDiscovered(int, javax.bluetooth.ServiceRecord[])
*/
public void servicesDiscovered(int transID, ServiceRecord[] servRecord)
{
if (servRecord != null)
{
for (int i = 0; i < servRecord.length; i++)
{
DataElement serviceNameElement = servRecord[i].getAttributeValue(0x0100);
String serviceName = (serviceNameElement.getValue().toString()).trim();
ServiceInfo info = new ServiceInfo();
info.name = serviceName;
serviceInfoVector.addElement(info);
serviceRecordVector.addElement(servRecord[i]);
}
}
}
/**
* 搜索服务结束回调方法<BR>
* 结束包含正常结束,手动终止或错误
*
* @param transID 搜索事务ID
* @param respCode 搜索响应码
* @see javax.bluetooth.DiscoveryListener#serviceSearchCompleted(int, int)
*/
public void serviceSearchCompleted(int transID, int respCode)
{
switch (respCode)
{
case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
{
setStatus(STATUS_SER_SEARCH_FINISH);
break;
}
case DiscoveryListener.SERVICE_SEARCH_ERROR:
{
setStatus(STATUS_SER_SEARCH_ERROR);
break;
}
default:
{
setStatus(STATUS_SER_SEARCH_FINISH);
break;
}
}
synchronized (bluelock)
{
bluelock.notifyAll();
}
}
/**
* 线程run方法<BR>
* 搜索设备
*
* @see java.lang.Runnable#run()
*/
public void run()
{
if (supportJSR82)
{
findDevices();
}
}
/**
* 根据服务URL创建连接
*
* @param url 从ServiceRecord中获取的服务URL
* @return 创建的连接
* @exception IOException 当创建连接失败时,抛出IO异常
*/
public Connection getConnection(String url) throws IOException
{
Connection conn = null;
try
{
setStatus(STATUS_CONNECTING);
conn = Connector.open(url);
setStatus(STATUS_CONNECT_OK);
// RemoteDevice rd = RemoteDevice.getRemoteDevice(conn);
}
catch (IOException e)
{
setStatus(STATUS_CONNECT_FAIL);
throw e;
}
return conn;
}
/**
* 根据服务记录创建连接
*
* @param service 搜索记录
* @return 创建的连接
* @exception IOException 当创建连接失败时,抛出IO异常
*/
public Connection getConnection(ServiceRecord service) throws IOException
{
String url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
return getConnection(url);
}
// -----------------> getter & setter
/**
* 获取搜索到的蓝牙设备列表<br />
* 如果要获取最终的设备列表,需要在status=STATUS_DEV_SEARCH_FINISH时,再调用此方法
*
* @return 搜索到的蓝牙设备列表
*/
public Vector getRemoteDeviceVector()
{
return remoteDeviceVector;
}
/**
* 获取搜索到的服务列表
*
* @return 搜索到的ServiceRecord列表
*/
public Vector getServiceRecordVector()
{
return serviceRecordVector;
}
/**
* 获取搜索到的服务信息列表
*
* @return 搜索到的ServiceRecord信息列表
*/
public Vector getServiceInfoVector()
{
return serviceInfoVector;
}
/**
* 获取当前状态
*
* @return 状态
*/
public int getStatus()
{
return status;
}
/**
* 设置状态
*
* @param status 要设置的状态
*/
public void setStatus(int status)
{
this.status = status;
}
/**
* 判断是否支持jsr82规范
*
* @return 是否支持蓝牙
*/
public boolean isSupportJSR82()
{
return supportJSR82;
}
/**
* 设置搜索过滤器
*
* @param filter 搜索设备时的过滤器
*/
public void setFilter(Filter filter)
{
this.filter = filter;
}
/**
* 获取设备过滤器
*
* @return 设备过滤器
*/
public Filter getFilter()
{
return filter;
}
/**
* 设备搜索过滤器<BR>
* 如果符合匹配条件,则将搜索到的设备加入搜索结果集合当中
*
* @author Adminstrator
* @version V1.0
*/
public static abstract class Filter
{
/**
* 判断设备是否符合过滤规则
*
* @param device 搜索到的设备
* @return 是否符合过滤规则
*/
public abstract boolean match(RemoteDevice device);
}
}
分享到:
相关推荐
**J2ME蓝牙编程详解** Java 2 Micro Edition (J2ME) 是一种Java平台,专为嵌入式设备和移动设备设计,如早期的智能手机和平板电脑。它提供了丰富的功能,包括支持无线通信,其中就包括蓝牙(Bluetooth)编程。在...
在J2ME手机蓝牙聊天系统中,蓝牙作为传输媒介,使得手机之间可以建立连接并进行数据通信,无需物理线缆连接。 **J2ME架构**:J2ME包含配置(Configurations)和配置文件(Profiles)。在这个聊天系统中,可能使用了...
简单j2me蓝牙OBEX传文件代码 http://blog.csdn.net/xiaoxiao108/archive/2011/03/10/6237233.aspx 最近想写一手机程序实现以下功能,在蓝牙的有效距离内,如果有其他手机的蓝牙设置为可见状态,自己的手机自动向其他...
《J2ME蓝牙实战入门》文档主要介绍了如何利用Java Micro Edition (J2ME)平台中的JSR82规范来开发蓝牙应用。JSR82,全称为Java APIs for Bluetooth Wireless Technology,提供了一套API,使得开发者能够在支持蓝牙的...
【J2ME蓝牙五子棋游戏源代码】是一款专为移动设备设计的、基于Java Micro Edition(J2ME)平台的轻量级游戏。这款五子棋游戏利用了J2ME提供的蓝牙通信功能,使玩家可以通过手机之间的蓝牙连接进行对战,增加了游戏的...
《J2ME蓝牙编程》这一主题深入探讨了在移动设备上开发Java蓝牙应用程序的技术与实践。J2ME(Java 2 Micro Edition)是Sun Microsystems为嵌入式和移动设备设计的Java平台版本,它提供了轻量级的Java运行环境,特别...
总结,J2ME蓝牙游戏的对战分析涉及了移动游戏开发的基础知识,如J2ME环境、用户界面设计、游戏循环,以及蓝牙通信技术,包括设备发现、连接建立和数据交换。五子棋游戏的实现则具体展示了如何结合这些技术,构建一个...
这个名为"j2me蓝牙_客户端_服务端_类.rar"的压缩包文件包含了一个基于Java ME(J2ME)平台的蓝牙开发示例,涵盖了客户端、服务端以及相关的类。下面我们将深入探讨这些知识点。 首先,Java ME(Java 2 Micro ...
《J2ME蓝牙五子棋游戏源代码解析》 J2ME(Java 2 Micro Edition)是...总之,J2ME蓝牙五子棋游戏源代码是学习移动设备编程和蓝牙通信的宝贵素材,它将理论知识与实际应用紧密结合,对于提升Java ME开发技能大有裨益。
总的来说,“J2ME手机蓝牙聊天”项目是一个实践性强、涵盖技术点丰富的课程设计,不仅涉及J2ME的基础编程,还涵盖了蓝牙通信的原理与应用。通过这个项目,开发者不仅可以深入理解J2ME平台,还能掌握蓝牙通信的核心...
总之,J2ME移动开发平台的搭建涉及Java SDK的安装、IDE的选择与配置,以及蓝牙功能的开发API学习。通过这个过程,你将能够创建并测试自己的J2ME应用程序,尤其是具备蓝牙通信功能的项目。记得实践是检验真理的唯一...
总之,J2ME手机蓝牙通讯的核心在于正确使用JSR-82提供的API,实现设备发现、服务搜索、连接建立、数据传输以及连接管理。通过熟练掌握这些步骤,开发者可以构建出功能完善的蓝牙应用,满足手机与各种蓝牙设备间的...
最后,文档"蓝牙五子棋.doc"可能包含了项目的详细设计、源代码注释或者测试报告,这些资料对于理解整个项目和学习J2ME蓝牙编程具有很大的帮助。 总的来说,基于J2ME的蓝牙五子棋项目是一个结合了基础编程、蓝牙通信...
总的来说,J2ME蓝牙五子棋项目展示了如何利用Java技术在移动设备上实现一个互动的、通过蓝牙连接的双人游戏。它涉及到了移动编程的多个方面,包括UI设计、游戏逻辑实现、设备间通信等,对于学习J2ME和蓝牙编程的...
1. **蓝牙API**:J2ME中的JSR-82(Java API for Bluetooth Wireless Technology)提供了与蓝牙设备交互的接口,包括搜索设备、建立连接、传输数据等。 2. **线程管理**:游戏逻辑和蓝牙通信通常需要在不同的线程中...
这个项目的核心是通过手机上的Java ME (Java 2 Micro Edition)平台,利用其提供的蓝牙API,实现与小车的无线通信。下面将详细阐述相关知识点。 1. **Java ME**:Java ME是Java在嵌入式设备和移动设备上的应用开发...
1. **蓝牙连接管理**:如何使用J2ME API进行蓝牙设备的搜索、连接和断开。 2. **数据交换**:如何编码和解码点菜信息,以及如何通过蓝牙接口进行数据传输。 3. **用户界面**:如何设计简单的图形用户界面(GUI)以...
《J2ME编写的蓝牙五子棋:源码解析与技术要点》 J2ME,全称Java 2 Micro Edition,是Java平台的一个版本,专为嵌入式设备和移动设备设计,如早期的智能手机和平板电脑。在移动通信领域,J2ME曾广泛应用于开发各种...