- 浏览: 203514 次
- 性别:
- 来自: 河源
文章分类
- 全部博客 (102)
- Hibernate IBatis (0)
- Spring (0)
- Struts2.x Struts1.x (0)
- Oracle (3)
- sql server (2)
- JavaME (15)
- MySql (0)
- Android (9)
- lwuit (10)
- .net (9)
- Ajax (3)
- UML (0)
- JavaSE——java基础 (4)
- Java web (3)
- 设计模式 (2)
- JSF (0)
- 服务器之:Tomcat (1)
- 计算机网络 (14)
- 操作系统 (5)
- 工具类 (7)
- Linux (0)
- 其他 (3)
- 经验总结 (3)
- 搜索引擎 (1)
- html (1)
- python (1)
- c (2)
- perl (1)
- Lisp (1)
最新评论
-
十口文:
谢谢你的分享!!
操作系统 教程 -
liu_shui8:
请问这是什么考试的试题?
谢谢!!!
操作系统试题及参考答案 -
JAVA言诚eye218:
这个在8.6中已经不能用了
myeclipse8.6正式版下载地址+注册码 -
liky1234567:
虽然是英语,还是耐心看完了
Simple Bluetooth Communication in J2ME -
xiao_feng68:
有个疑问想问博主:问什么直接使用组件事件得到的media是都是 ...
zk fileupload
蓝牙协议 关于蓝牙的一个鲜为人知的事实是:它即便不是世界上配置最为广泛并且最成功的 SOA(面向服务架构)系统,那么也是其中之一。蓝牙技术得到广泛的安装采用(部署的设备超过 5 亿台),并且当前的数据估计每周都有另外五百万台蓝牙设备送出。远在“面向服务架构”成为专门术语之前,蓝牙协议就已经提供了服务注册、服务发现和服务调用机制。 因此,蓝牙协议结合了面向服务架构并采用 HTTP 和 FTP 之类的其他协议中熟悉使用的客户端/服务器通信架构:在客户端发出请求之前,服务器耐心地等待。当前市场上的蓝牙设备能够以 3 Mb/s 的速率进行通信,并且可以支持立体声无线音频。以下图 1 显示了蓝牙协议栈的各个层。
图 1:蓝牙协议栈及其层 因为本文的重点是 OBEX,所以我没有讲述图 1 中所有层的细节,但是我确实希望提供关于主要的支持 OBEX 层的一些详细信息。如您所见,该栈的主要协议层之一是 L2CAP(逻辑链路控制和适配协议)。L2CAP 用作其他所有上层之间信息包数据的多路复用器。另一方面,RFCOMM 称为“虚拟串行端口”层。需要与支持数据流的设备通信时,RFCOMM 用起来不错。OBEX(代表对象交换)是最适合文件传输的协议层。借助 OBEX,可以创建消息并向包含有效载荷(也就是要发送的文件)的远程蓝牙设备发送消息以及重要元数据(如文件名称、文件大小和文件类型)。 蓝牙模式 蓝牙模式允许各种性能不同的蓝牙设备进行交互和协作。每个模式都是一个针对具体目的定义功能的用例。例如,如果希望通过移动设备向使用打印机,则两台设备都必须实现基本打印模式。或者例如,如果要同步台式机和 PDA 的联系人列表,这两台设备必须都支持同步模式。下面的表 1 列出使用蓝牙栈 OBEX 协议层的模式。 表 1. 当前基于 OBEX 的模式 根据蓝牙 SIG,已定义的蓝牙模式有 30 多种,涉及音频分配到个人网。在本文中,我们将使用 JSR-82 API 实现对象推送模式,并向任意支持 OPP 的蓝牙设备发送图像。 创建 ImageSender Midlet ImageSender Midlet 是使用 NetBeans 5.0 IDE 的 NetBeans Mobility Pack 创建的。Mobility Pack 包含一个非常方便的 GUI 设计工具,它允许移动开发人员使用拖放技术快速创建移动应用程序。ImageSender Midlet 包含若干个静态 GUI 组件(也就是非动态创建的组件),Mobility Pack 在创建 GUI 组件及其之间的工作流方面非常高效。以下图 2 描述了用于创建 ImageSender Midlet 的 NetBeans 项目。
模式名称
缩写
UUID
对象推送模式
OPP
0x1105
文件传输模式
FTP
0x1106
同步模式
SYP
0x1104
静态图像传输模式
BIP
0x111A
电话簿访问模式
PBAP
0x1130
基本打印模式
BPP
0x1122
图 2:用来创建 ImageSender Midlet 的 NetBeans 项目 为了使 ImageSender 完成其任务(如从文件系统读取文件,以及向远程蓝牙设备发送数据),ImageSender 所使用的内部类封装了以下三个重要功能领域: 读取文件并遍历文件系统(将由 FileNavigator 处理) 发现远程蓝牙设备(将由 BTUtility 处理) 使用对象推送模式向远程蓝牙设备发送文件(将由 FilePusher 处理) 学习了这些预备知识,下面开始实现! ImageSender.FileNavigator 以下图 3 是一个程序表,它显示了 ImageSender Midlet 和其内部类(FileNavigator)之间的交互,FileNavigator 专门用来读取和遍历移动设备的文件系统。
图 3:显示 FileNavigator 内部类用法的程序图 首先,ImageSender 获取一个 FileNavigator 实例并调用 getListofFolder() 方法,该方法返回一个 javax.microedition.lcdui.List。而 FileNavigator 将使用 JSR-75 File Connection API 的 FileSystemRegsitry 类获取文件系统“根”的枚举 ,也就是设备的载入点。如果移动设备包含可移动介质(如 SD 内存卡),它也将在枚举中显示。对于文件系统的每个根,都对其建立一个 FileConnection 以确定它是文件还是文件夹。 这是必需的,因为您肯定希望以不同的方式处理它们(也就是,如果该项目是文件夹,您希望遍历该文件夹,但是如果该项目是文件,那么您将希望打开该文件以获得其内容)。枚举完之后,FileNavigator 内部类将向 ImageSender 返回一个 List,ImageSender 将简单地在该移动设备上显示 List,如以下图 4 所示。 图 4:ImageSender 显示目录中的文件和文件夹列 因为 FileNavigator 内部类实现了 CommandListener 接口,所以它将处理来自该用户接口的所有更改目录或选择文件的请求。该方法使得父类 ImageSender 不再负责响应用户的输入并了解如何处理该输入。内部类已经拥有对 JSR-75 类的引用,这些类允许其连接到文件系统,所以非常适合处理用户的请求并处理文件系统。下面是 FileNavigator 的 commandAction() 方法的一部分;当用户选择该列表中的项目时将执行这部分代码: 可以看到,如果用户选择了一个文件夹,FileNavigator 将遍历该文件夹,返回另一个列表并显示它。然后,如果该用户选择一个文件,FileNavigator 内部类将打开到该文件的 FileConnection 并以名为“file”的字节数组读取其内容。 ImageSender.BTUtility ImageSender Midlet 使用的第二个辅助类是 BTUtility。您可能会猜到,BTUtility 内部类封装了其余代码所调用的所有 JSR-82 蓝牙 API 方法。BTUtility 主要向 ImageSender Midlet 提供两个领域的功能:发现附近的远程蓝牙设备,并对这些设备执行服务搜索。图 5 为显示 ImageSender 如何使用 BTUtility 的程序图。 图 5:描述 ImageSender 和 BTUtility 之间交互的程序图 如上所示,ImageSender 获得了 BTUtility 的新实例之后,该实例包含对 LocalDevice 和 DiscoveryAgent 类的引用。为了发现附近的蓝牙设备,必须调用 DiscoveryAgent.startInquiry()。该实现将异步调用在该区域发现的每台蓝牙设备的 deviceDiscovered() 方法。最后,如果没有发现更多蓝牙设备,JVM 将调用 inquiryCompleted() 方法。图 6 显示了 BTUtility 类发现的启用蓝牙技术的设备列表。 图 6:BTUtility 类所发现的蓝牙设备 BTUtility 执行的另一项工作是搜索远程蓝牙设备上的服务。如以下图 7 所示,搜索服务过程比发现设备需要占用更多 CPU 时间。这就是为什么设备发现过程可以从 BTUtility 的构造函数发起,但是服务搜索部分必须以 Thread 启动。 图 7:使用 BTUtility 搜索远程蓝牙设备上的服务。 幸运的是,BTUtility 扩展了 Thread 类,因此可防止该用户接口挂起。当 BTUtility 调用 DiscoveryAgent.searchServices() 时,如果发现匹配的服务,JVM 将异步调用其 serviceDiscovered() 方法。服务搜索过程完成时,JVM 将调用其 serviceSearchCompleted() 方法。作为备用方式,可以调用 DiscoveryAgent.selectService(),但是根据 JSR-82 规范,它只能返回附近一个服务提供商的 connectionURL。回顾上面的图 6 可知,在大多数环境中,您不知道文件将发送给谁。下面是完整的 BTUtility 清单: ...
if(isFolderSelected == true){
// the user selected a folder, so navigate down it
String folderUrl = (String)curr_dir_urls.elementAt(selectedIndex);
getDisplay().setCurrent(fileNavigator.getListofFolder(folderUrl, false));
} else {
getDisplay().setCurrent(get_fileSelectedAlert(), displayable);
// the user has obviously selected a file, so let's read it in
String file_url = (String)curr_dir_urls.elementAt(selectedIndex);
...
fileConn = (FileConnection) Connector.open(file_url);
InputStream is = fileConn.openInputStream();
// now let's read the file in into our byte[]
file = new byte[(int)fileConn.fileSize()];
is.read(file);
is.close();
...
在 BTUtility 内部类中,您可能会注意到在多处都使用了十六进制值。尤其是: 现在,如果您记得上面的表 1 中的值,就可以理解为什么创建 0x1105 UUID 值,因为它是对象推送模式的 UUID。然而,在 attrSet 中也使用了 0x0100 值,通过它可以了解远程服务的服务名称。 ImageSender.FilePusher 到目前为止我们有哪些收获?首先,我们拥有一个可以使用 JSR-75 FileConnection API 浏览文件系统的 Midlet(当然这都是内部类 FileNavigator 实现的)。Midlet 还能够发现附近的远程蓝牙设备并确定该设备上可用的服务(这项功能是由另一个内部类 BTUtility 提供的)。所以,现在只需实现使用 BBEX 向远程蓝牙设备发送文件的机制。 FilePusher 通过使用 org.netbeans.microedition.lcdui.WaitScreen(如图 8 所示)并实现 org.netbeans.microedition.util.CancellableTask(它扩展了 Runnable)轻而易举地完成了这项任务。 /**
* This is an inner class that is used for finding
* Bluetooth devices in the vicinity
*
*/
class BTUtility extends Thread implements DiscoveryListener {
Vector remoteDevices = new Vector();
Vector deviceNames = new Vector();
DiscoveryAgent discoveryAgent;
// obviously, 0x1105 is the UUID for
// the Object Push Profile
UUID[] uuidSet = {new UUID(0x1105) };
// 0x0100 is the attrubute for the service name element
// in the service record
int[] attrSet = {0x0100};
public void run(){
try {
RemoteDevice remoteDevice = (RemoteDevice)remoteDevices.elementAt(get_devicesList().getSelectedIndex());
discoveryAgent.searchServices(attrSet, uuidSet, remoteDevice , this);
} catch(Exception e) {
e.printStackTrace();
}
}
public BTUtility() {
// clear the list out, just in case it's not
get_devicesList().deleteAll();
try {
LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent();
//deviceDiscoveryPanel.updateStatus(" Searching for Bluetooth devices in the vicinity...n");
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
} catch(Exception e) {
e.printStackTrace();
}
}
public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {
try{
remoteDevices.addElement(remoteDevice);
} catch(Exception e){
e.printStackTrace();
}
}
public void inquiryCompleted(int discType) {
if (remoteDevices.size() > 0) {
// the discovery process was a success
// so let's out them in a List and display it to the user
for (int i=0; i UUID[] uuidSet = {new UUID(0x1105) };
// 0x0100 is the attribute for the service name element
// in the service record
int[] attrSet = {0x0100};
图 8:使用 WaitScreen 的 NetBeans 流设计快照 如上图所示,WaitScreen 将执行 CPU 密集型任务(如执行网络 I/O)。该任务必须实现 CancellableTask 接口(正是 FilePusher 内部类实现了该功能)。使用 IDE,可以用图形的方式连接到成功或失败屏幕(具体取决于操作结果)。FilePusher 代码如以下列表所示: 现在,通过研究 ObjectPusher 内部类的 run() 方法来深入地了解 OBEX 协议。了解 OBEX 协议的最佳方式是观察 OBEX 客户端和服务器之间的交互,如以下图 9 所示: class FilePusher implements CancellableTask{
// this is used for the purposes of the Cancellable task
boolean isOperationFailed = false;
// this is the failure message used by the Cancellable task
String failure_message = null;
// this is the connection object to be used for
// bluetooth i/o
Connection connection = null;
public FilePusher(){
}
// this is method 1 of 4 methods needed to be implemented by
// the CancellableTask interface
public boolean cancel(){
// sorry this can't be cancelled
return false;
}
// this is method 2 of 4 needed to be implemented by
// the CancellableTask interface
public String getFailureMessage(){
// of course, if there's no problem
// then this method should return null as specified by the javadoc
return failure_message;
}
// this is method 3 of 4 needed to be implemented by
// the CancellableTask interface
public boolean hasFailed(){
return isOperationFailed;
}
// this is method 4 of 4 needed to be implemented by
// the CancellableTask interface
public void run(){
try{
connection = Connector.open(btConnectionURL);
// connection obtained
// now, let's create a session and a headerset objects
ClientSession cs = (ClientSession)connection;
HeaderSet hs = cs.createHeaderSet();
// now let's send the connect header
cs.connect(hs);
hs.setHeader(HeaderSet.NAME, filename);
hs.setHeader(HeaderSet.TYPE, "image/jpeg");
hs.setHeader(HeaderSet.LENGTH, new Long(file.length));
Operation putOperation = cs.put(hs);
OutputStream outputStream = putOperation.openOutputStream();
outputStream.write(file);
// file push complete
outputStream.close();
putOperation.close();
cs.disconnect(null);
connection.close();
} catch (Exception e){
isOperationFailed = true;
failure_message = e.toString();
}
}
}
图 9:使用 OBEX 协议的客户端和服务器交互示例 图 9 中所示的场景发生在客户端和服务器建立了物理蓝牙连接的情况下,在 FilePusher 中,这是通过以下代码实现的: 建立了连接之后,就应该通过将该连接对象更改成 ClientSession 对象来创建客户端和服务器之间的会话: 现在,建立会话之后,再看图 9。请注意客户端发送 OBEX 操作(如 Connect、Setpath、Get、Push 等),服务器将借助 OBEX Response Code(160、161、193、196等)响应客户端。以下代码展示如何发送 Connect 操作: 从以下代码片断可以看出,OBEX 是通过蓝牙技术传输文件的首选方式(相比 RFCOMM 或 L2CAP),因为可以使用报头设置关于要传输文件的元数据: 这样,接受者就能在接收该文件之前了解文件的名称、文件类型和大小,而这是蓝牙栈中其他协议层不支持的强大功能。现在,设置完合适的报头之后,将向服务器发送 Put 操作: 该方法返回时,将得到一个 Operation 对象,您可以对其打开 OutputStream 并发送存储在名为“file”的字节数组中的文件数据(如果记得的话,可以知道我们是从 FileNavigator 内部类填充“file”的)。现在如果想了解服务器的响应代码,可以对 Operation 调用 getResponseCodes() 方法。 因此,使用从 putOperation 打开的 OutputStream 向目的地发送文件之后,发送最后的 OBEX 操作来完成程序:Disconnect Operation。 结束语 可以看出,创建使用 JSR-82 和 JSR-75 API 进行无线图像传输的复合应用程序并不需要太多工作。尽管本文展示如何通过 OBEX 传输图像,但是您会发现可以轻松修改这些代码来发送文件类型。享受编码的乐趣吧! connection = Connector.open(btConnectionURL);
// connection obtained // now, let's create a session and a headerset object
ClientSession cs = (ClientSession)connection; // now let's send the connect operation
cs.connect(hs); hs.setHeader(HeaderSet.NAME, filename);
hs.setHeader(HeaderSet.TYPE, "image/jpeg");
hs.setHeader(HeaderSet.LENGTH, new Long(file.length)); Operation putOperation = cs.put(hs);
cs.disconnect(null);
转载; http://tech.ddvip.com/2008-12/1229937389102020.html
发表评论
-
深入分析JAD和 MANIFEST.MF文件
2010-04-28 01:43 1771从前面的分析 中,我 ... -
J2ME字符串split方法
2010-04-27 20:07 1403/** * Split string into mu ... -
自己收集JavaME的相关资料
2010-04-15 02:05 10311、《WTK进阶使用教程》网址:http:// ... -
JavaME 到底可以干些什么
2010-04-10 22:11 1350最近在做一个JavaME的项目,发现JavaME也不 ... -
Simple Bluetooth Communication in J2ME
2010-01-07 10:00 2438最简单的蓝牙操作步骤,一步一步教你如何操作,它的流程很 ... -
BlueTooth探索系列(一)---JSR082 API框架剪影
2009-12-16 20:25 1701可以自由转载, 转载请保留下面的作者信息:作者 cleverp ... -
J2ME 串口编程
2009-12-09 16:34 2140Javax.comm是Sun公司提供的,用于开发平台独立的通讯 ... -
JSR82 API 介绍
2009-12-08 23:24 1910蓝牙是一种低成本、 ... -
j2ME多线程网络编程
2009-12-08 22:07 2020网络编程中的多 ... -
在Java ME中通过蓝牙发现设备并传送文件
2009-12-08 22:00 1320在Java ME设备上 ... -
蓝牙应用
2009-12-08 21:11 1131网易科技讯 4月13 ... -
基于JSR82的蓝牙应用开发手记
2009-12-08 21:08 2185目目标:基于JSR82的蓝牙应用,实现手机和PC之 ... -
CLDC API简要介绍
2009-12-06 09:16 723* 介绍 ... -
j2me框架大全
2009-12-05 01:06 4859J2ME Polish J2ME Po ...
相关推荐
赠送jar包:jsr311-api-1.1.1.jar; 赠送原API文档:jsr311-api-1.1.1-javadoc.jar; 赠送源代码:jsr311-api-1.1.1-sources.jar; 赠送Maven依赖信息文件:jsr311-api-1.1.1.pom; 包含翻译后的API文档:jsr311-api...
赠送原API文档:undertow-websockets-jsr-2.1.7.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.1.7.Final-sources.jar; 赠送Maven依赖信息文件:undertow-websockets-jsr-2.1.7.Final.pom; 包含翻译...
赠送jar包:jsr311-api-1.1.1.jar; 赠送原API文档:jsr311-api-1.1.1-javadoc.jar; 赠送源代码:jsr311-api-1.1.1-sources.jar; 赠送Maven依赖信息文件:jsr311-api-1.1.1.pom; 包含翻译后的API文档:jsr311-api...
webservice中用到的jar,xfire-jsr181-api-1.0-M1.jar,xfire-jsr181-api-1.0-M1.jar
赠送原API文档:undertow-websockets-jsr-2.1.7.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.1.7.Final-sources.jar; 赠送Maven依赖信息文件:undertow-websockets-jsr-2.1.7.Final.pom; 包含翻译...
下面是一个简单的示例,展示如何使用JSR-94 API执行规则: ```java // 获取RuleServiceProvider RuleServiceProvider serviceProvider = RuleServiceProviderManager.getProvider(); // 创建RuleRuntime Rule...
赠送原API文档:undertow-websockets-jsr-2.2.14.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.2.14.Final-sources.jar; 赠送Maven依赖信息文件:undertow-websockets-jsr-2.2.14.Final.pom; 包含...
赠送原API文档:undertow-websockets-jsr-2.2.14.Final-javadoc.jar; 赠送源代码:undertow-websockets-jsr-2.2.14.Final-sources.jar; 赠送Maven依赖信息文件:undertow-websockets-jsr-2.2.14.Final.pom; 包含...
`validation-api-1.0.0.GA.jar`是JSR-303验证API的实现,包含所有定义的验证注解和接口。这个API定义了验证的核心接口,如Validator、Validation和ConstraintValidator,以及各种预定义的验证注解。开发人员可以直接...
在实际开发中,JSR 250 API 1.0 常常与Spring框架、CDI(Contexts and Dependency Injection)等结合使用,增强应用的依赖管理和生命周期管理。了解并熟练运用这些注解,能够极大地提高开发效率,减少手动管理对象...
- **JSR-257-Specification-License-for-Implementation.pdf**:包含了实施此规范的许可协议,规定了如何合法使用和分发JSR-257 API的实现。 - **Instructions for Implementation Spec License.pdf**:可能是关于...
jsr是Java Specification Requests的缩写,意思是Java 规范提案。
包含翻译后的API文档:jackson-datatype-jsr310-2.12.5-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.5; 标签:fasterxml、jackson、datatype、...
标题 "xfire-jsr181-api-1.0-实例化webservic" 指的是使用XFire框架结合JSR 181规范来创建和实例化Web服务的过程。XFire是一款早期的Java Web服务实现,它提供了一种简单、高性能的方式来创建和消费SOAP服务。JSR ...
包含翻译后的API文档:jsr305-3.0.2-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.google.code.findbugs:jsr305:3.0.2; 标签:findbugs、jsr305、google、jar包、java、中英对照文档; 使用方法:...
包含翻译后的API文档:jackson-datatype-jsr310-2.11.4-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.4; 标签:fasterxml、jackson、...
java.lang.ClassNotFoundException: javax.measure.converter.ConversionException所需的jar
包含翻译后的API文档:jackson-datatype-jsr310-2.13.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1; 标签:jackson、jsr310、datatype、...
jsr311-api-1.0.jar的jar包,与以前的版本不同,且使用广泛点
包含翻译后的API文档:jackson-datatype-jsr310-2.9.7-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.7; 标签:jackson、jsr310、...