J2ME蓝牙bluetooth实战入门.docx
《J2ME蓝牙bluetooth实战入门.docx》由会员分享,可在线阅读,更多相关《J2ME蓝牙bluetooth实战入门.docx(23页珍藏版)》请在冰豆网上搜索。
J2ME蓝牙bluetooth实战入门
窗体顶端
窗体底端
J2ME蓝牙(bluetooth)实战入门
Author:
一滴蔚蓝色|
Date:
2007-07-29|
View:
2106|
开发技术- 程序设计|
Digg:
0
概述
目前,很多手机已经具备了蓝牙功能。
虽然MIDP2.0没有包括蓝牙API,但是JCP定义了JSR82, Java APIs for Bluetooth Wireless Technology (JABWT).这是一个可选API,很多支持MIDP2.0的手机已经实现了,比如Nokia 6600, Nokia 6670,Nokia7610等等。
对于一个开发者来说,如果目标平台支持JSR82的话,在制作联网对战类型游戏或者应用的时候,蓝牙是一个相当不错的选择。
本文给出了一个最简单的蓝牙应用的J2ME程序,用以帮助开发者快速的掌握JSR82。
该程序分别在2台蓝牙设备上安装后,一台设备作为服务端先运行,一台设备作为客户端后运行。
在服务端上我们发布了一个服务,该服务的功能是把客户端发过来的字符串转变为大写字符串。
客户端起动并搜索到服务端的服务后,我们就可以从客户端的输入框里输入任意的字符串,发送到服务端去,同时观察服务端的反馈结果。
本文并不具体讲述蓝牙的运行机制和JSR82的API结构,关于这些知识点,请参考本文的参考资料一节,这些参考资料会给你一个权威的精确的解释。
实例代码
该程序包括3个java文件。
一个是MIDlet,另外2个为服务端GUI和客户端GUI。
该程序已经在wtk22模拟器和Nokia 6600,Nokia 6670两款手机上测试通过。
StupidBTMIDlet.java
1.import javax.microedition.lcdui.Alert;
2.import javax.microedition.lcdui.AlertType;
3.import javax.microedition.lcdui.Command;
4.import javax.microedition.lcdui.CommandListener;
5.import javax.microedition.lcdui.Display;
6.import javax.microedition.lcdui.Displayable;
7.import javax.microedition.lcdui.List;
8.import javax.microedition.midlet.MIDlet;
9.import javax.microedition.midlet.MIDletStateChangeException;
10./**
11. * @author Jagie
12. *
13. * MIDlet
14. */
15.public class StupidBTMIDlet extends MIDlet implements CommandListener {
16. List list;
17. ServerBox sb;
18. ClientBox cb;
19. /*
20. * (non-Javadoc)
21. *
22. * @see javax.microedition.midlet.MIDlet#startApp()
23. */
24. protected void startApp() throws MIDletStateChangeException {
25. list = new List("傻瓜蓝牙入门", List.IMPLICIT);
26. list.append("Client", null);
27. list.append("Server", null);
28. list.setCommandListener(this);
29. Display.getDisplay(this).setCurrent(list);
30. }
31.
32. /**
33. * debug方法
34. * @param s 要显示的字串
35. */
36. public void showString(java/lang/String.java.html"target="_blank">String s) {
37. Displayable dp = Display.getDisplay(this).getCurrent();
38. Alert al = new Alert(null, s, null, AlertType.INFO);
39. al.setTimeout(2000);
40. Display.getDisplay(this).setCurrent(al, dp);
41. }
42.
43. /**
44. * 显示主菜单
45. *
46. */
47. public void showMainMenu() {
48. Display.getDisplay(this).setCurrent(list);
49. }
50.
51. protected void pauseApp() {
52. // TODO Auto-generated method stub
53. }
54. public void commandAction(Command com, Displayable disp) {
55. if (com == List.SELECT_COMMAND) {
56. List list = (List) disp;
57. int index = list.getSelectedIndex();
58. if (index == 1) {
59. if (sb == null) {
60. sb = new ServerBox(this);
61. }
62. sb.setString(null);
63. Display.getDisplay(this).setCurrent(sb);
64. } else {
65. //每次都生成新的客户端实例
66. cb = null;
67. java/lang/System.java.html"target="_blank">System.gc();
68. cb = new ClientBox(this);
69. Display.getDisplay(this).setCurrent(cb);
70. }
71. }
72. }
73. protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
74. // TODO Auto-generated method stub
75. }
76.}
ClientBox.java
1.import java.io.java/io/DataInputStream.java.html"target="_blank">DataInputStream;
2.import java.io.java/io/DataOutputStream.java.html"target="_blank">DataOutputStream;
3.import java.io.java/io/IOException.java.html"target="_blank">IOException;
4.import java.util.java/util/Vector.java.html"target="_blank">Vector;
5.import javax.microedition.io.Connector;
6.import javax.microedition.io.StreamConnection;
7.import javax.microedition.lcdui.Command;
8.import javax.microedition.lcdui.CommandListener;
9.import javax.microedition.lcdui.Displayable;
10.import javax.microedition.lcdui.Form;
11.import javax.microedition.lcdui.Gauge;
12.import javax.microedition.lcdui.StringItem;
13.import javax.microedition.lcdui.TextField;
14.//jsr082 API
15.import javax.bluetooth.BluetoothStateException;
16.import javax.bluetooth.DeviceClass;
17.import javax.bluetooth.DiscoveryAgent;
18.import javax.bluetooth.DiscoveryListener;
19.import javax.bluetooth.LocalDevice;
20.import javax.bluetooth.RemoteDevice;
21.import javax.bluetooth.ServiceRecord;
22.import javax.bluetooth.UUID;
23./**
24. * 客户端GUI
25. * @author Jagie
26. *
27. * TODO To change the template for this generated type comment go to
28. * Window - Preferences - Java - Code Style - Code Templates
29. */
30.public class ClientBox extends Form implements java/lang/Runnable.java.html"target="_blank">Runnable, CommandListener,
31. DiscoveryListener {
32.
33. //字串输入框
34. TextField input = new TextField(null, "", 50, TextField.ANY);
35. //loger
36. StringItem result = new StringItem("结果:
", "");
37. private DiscoveryAgent discoveryAgent;
38.
39. private UUID[] uuidSet;
40. //响应服务的UUID
41. private static final UUID ECHO_SERVER_UUID = new UUID(
42. "F0E0D0C0B0A000908070605040302010", false);
43. //设备集合
44. java/util/Vector.java.html"target="_blank">Vector devices = new java/util/Vector.java.html"target="_blank">Vector();
45. //服务集合
46. java/util/Vector.java.html"target="_blank">Vector records = new java/util/Vector.java.html"target="_blank">Vector();
47.
48. //服务搜索的事务id集合
49. int[] transIDs;
50. StupidBTMIDlet midlet;
51. public ClientBox(StupidBTMIDlet midlet) {
52. super("");
53. this.midlet=midlet;
54.
55. this.append(result);
56.
57. this.addCommand(new Command("取消",Command.CANCEL,1));
58. this.setCommandListener(this);
59.
60. new java/lang/Thread.java.html"target="_blank">Thread(this).start();
61. }
62.
63. public void commandAction(Command arg0, Displayable arg1) {
64. if(arg0.getCommandType()==Command.CANCEL){
65. midlet.showMainMenu();
66. }else{
67. //匿名内部Thread,访问远程服务。
68. java/lang/Thread.java.html"target="_blank">Thread fetchThread=new java/lang/Thread.java.html"target="_blank">Thread(){
69. public void run(){
70. for(int i=0;i71. ServiceRecord sr=(ServiceRecord)records.elementAt(i);
72. if(accessService(sr)){
73. //访问到一个可用的服务即可
74. break;
75. }
76. }
77. }
78. };
79. fetchThread.start();
80. }
81.
82. }
83.
84.
85. private boolean accessService(ServiceRecord sr){
86. boolean result=false;
87. try {
88. java/lang/String.java.html"target="_blank">String url = sr.getConnectionURL(
89. ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
90. StreamConnection conn = (StreamConnection) Connector.open(url);
91.
92. java/io/DataOutputStream.java.html"target="_blank">DataOutputStream dos=conn.openDataOutputStream();
93. dos.writeUTF(input.getString());
94. dos.close();
95. java/io/DataInputStream.java.html"target="_blank">DataInputStream dis=conn.openDataInputStream();
96. java/lang/String.java.html"target="_blank">String echo=dis.readUTF();
97. dis.close();
98. showInfo("反馈结果是:
"+echo);
99. result=true;
100.
101. } catch (java/io/IOException.java.html"target="_blank">IOException e) {
102.
103. }
104. return result;
105. }
106. public synchronized void run() {
107. //发现设备和服务的过程中,给用户以Gauge
108. Gauge g=new Gauge(null,false,Gauge.INDEFINITE,Gauge.CONTINUOUS_RUNNING);
109. this.append(g);
110. showInfo("蓝牙初始化...");
111. boolean isBTReady = false;
112. try {
113. LocalDevice localDevice = LocalDevice.getLocalDevice();
114. discoveryAgent = localDevice.getDiscoveryAgent();
115. isBTReady = true;
116. } catch (java/lang/Exception.java.html"target="_blank">Exception e) {
117. e.printStackTrace();
118. }
119. if (!
isBTReady) {
120. showInfo("蓝牙不可用");
121. //删除Gauge
122. this.delete
(1);
123. return;
124. }
125. uuidSet = new UUID[2];
126. //标志我们的响应服务的UUID集合
127. uuidSet[0] = new UUID(0x1101);
128. uuidSet[1] = ECHO_SERVER_UUID;
129.
130. try {
131. discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
132. } catch (BluetoothStateException e) {
133. }
134. try {
135. //阻塞,由inquiryCompleted()回调方法唤醒
136. wait();
137. } catch (java/lang/InterruptedException.java.html"target="_blank">InterruptedException e1) {
138.
139. e1.printStackTrace();
140. }
141. showInfo("设备搜索完毕,共找到"+devices.size()+"个设备,开始搜索服务");
142. transIDs = new int[devices.size()];
143. for (int i = 0; i < devices.size(); i++) {
144. RemoteDevice rd = (RemoteDevice) devices.elementA