|
|
Source Code for SPPClientMain.java
001 package net.benhui.btgallery.spp;
002
003 import javax.microedition.midlet.*;
004 import javax.microedition.lcdui.*;
005 import javax.microedition.io.*;
006 import java.io.*;
007 import javax.bluetooth.*;
008 import java.util.*;
009 import net.benhui.btgallery.*;
010
011 /**
012 *
013 * <p>Title: Example Serial Port Profile Client Main MIDlet</p>
014 * <p>Description: Important areas are doSSPSentMessage() and Listener inner class.</p>
015 * @author Ben Hui (www.benhui.net)
016 * @version 1.0
017 *
018 * LICENSE:
019 * This code is licensed under GPL. (See http://www.gnu.org/copyleft/gpl.html)
020 */
021
022 public class SPPClientMain extends MIDlet implements CommandListener
023 {
024 // commonly used singleton object
025 public static SPPClientMain instance;
026 public static Display display;
027
028 // GUI component/screen
029 private SPPClientUI sppclientui = null;
030 private InputMsgUI inputmsgui = null;
031
032 // Bluetooth singleton object
033 LocalDevice device;
034 DiscoveryAgent agent;
035
036 // list of RemoteDevice discovered
037 public static Vector devices = new Vector();
038 // list of DeviceClass discovered (not used in this example)
039 public static Vector deviceClasses = new Vector();
040 // list of ServiceRecrod discovered for one RemoteDevice
041 public static Vector services = new Vector();
042 // index of the currently selected RemoteDevice, obtained from DeviceDiscoveryUI
043 public static int selectedDevice = -1;
044
045 public SPPClientMain()
046 {
047 instance = this;
048 }
049
050 /**
051 * Implements MIDlet lifecycle
052 */
053 public void startApp()
054 {
055 display = Display.getDisplay(this);
056
057 sppclientui = new SPPClientUI();
058 inputmsgui = new InputMsgUI();
059
060
061 // show list of device.
062 // it is an empty list at start up
063 sppclientui.showui();
064 display.setCurrent(sppclientui);
065
066 }
067
068 /**
069 * Implements MIDlet lifecycle
070 */
071 public void pauseApp() {
072 }
073
074 /**
075 * Implements MIDlet lifecycle
076 */
077 public void destroyApp(boolean unconditional)
078 {
079 }
080
081 /**
082 * Exit MIDlet
083 */
084 public static void quitApp()
085 {
086 instance.destroyApp(true);
087 instance.notifyDestroyed();
088 instance = null;
089 }
090
091 // utility function
092 public static void log(String s)
093 {
094 System.out.println(s);
095 }
096
097 /**
098 * An utility function that show a alert box that display an exception message.
099 * @param e
100 * @param next_screen
101 */
102 public void showExceptionAlert( Exception e, Screen next_screen )
103 {
104 Alert alert = new Alert( "Problem", "Exception: "+e.getClass().getName()+" "+e.getMessage(), null, AlertType.ERROR );
105 alert.setTimeout( Alert.FOREVER );
106 display.setCurrent( alert, next_screen );
107 }
108
109 /**
110 * Handle user action and input.
111 * All GUI Command are directed to this function for simplicity of this demo.
112 * @param c
113 * @param d
114 */
115 public void commandAction(Command c, Displayable d)
116 {
117 if ( d == sppclientui && c.getLabel().equals("Inquiry") )
118 {
119 try
120 {
121 // clear previous values first
122 devices.removeAllElements();
123 deviceClasses.removeAllElements();
124
125 //
126 // initialize the JABWT stack
127 device = LocalDevice.getLocalDevice(); // obtain reference to singleton
128 device.setDiscoverable(DiscoveryAgent.GIAC); // set Discover mode to LIAC
129 agent = device.getDiscoveryAgent(); // obtain reference to singleton
130
131 // start device discovery
132 // and direct discovery response to Listener object
133 agent.startInquiry( DiscoveryAgent.GIAC, new Listener() );
134
135 // tell user to wait..
136 sppclientui.setMsg("[Please Wait...]");
137
138 } catch ( BluetoothStateException e )
139 {
140 e.printStackTrace();
141 showExceptionAlert( e, sppclientui );
142
143 }
144
145 } else if ( d == sppclientui && c.getLabel().equals("Send") )
146 {
147 // display a input screen for user to enter a message
148 selectedDevice = sppclientui.getSelectedIndex();
149
150 // make sure user did select a device from the GUI list
151 if ( selectedDevice == -1 || selectedDevice >= devices.size() )
152 {
153 Alert alert = new Alert( "Problem", "No device selected", null, AlertType.ERROR );
154 alert.setTimeout( Alert.FOREVER );
155 display.setCurrent( alert, sppclientui );
156
157 return;
158 }
159
160
161 display.setCurrent( inputmsgui );
162
163 } else if ( d == sppclientui && c.getLabel().equals("Exit") )
164 {
165 // exit application
166 quitApp();
167 } else if ( d == inputmsgui && c.getLabel().equals("OK") )
168 {
169 // user press OK on message input screen
170 services.removeAllElements();
171
172 // search for SerialPort service on selected device
173 RemoteDevice remoteDevice =
174 (RemoteDevice) devices.elementAt( selectedDevice);
175 try {
176 // search on SerialPort 0x1101
177 agent.searchServices( null, // null = just retrieve the default attributes
178 new UUID[]{ new UUID( 0x1101 ) }, // 0x1100 - SerialPort Profile
179 remoteDevice,
180 new Listener()); // direct discovery response to Listener object
181 }
182 catch (BluetoothStateException ex) {
183 ex.printStackTrace();
184 }
185
186 }
187 }
188
189 /**
190 * Send a message to the first ServiceRecord using Serial Port Profile.
191 * This is assumed that the first service is a SPP service.
192 * @param msg
193 */
194 public void doSSPSentMessage(String msg)
195 {
196 ServiceRecord r = (ServiceRecord) services.elementAt( 0 );
197
198 // obtain the URL reference to this service on remote device
199 String url = r.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false );
200
201 try
202 {
203 // obtain connection and stream to this service
204 StreamConnection con = (StreamConnection) Connector.open( url );
205 DataOutputStream out = con.openDataOutputStream();
206
207 // write data into serial stream
208 out.writeUTF( msg );
209 out.flush();
210
211 // this wait is artificial, the purpose to do wait until the
212 // server side really receive the message before we close the connection
213 // in theory, this is not necessary, but when I use the Rococo simulator,
214 // sometimes the connection dropped on the server side when I close it here
215 // it may be a bug in Rococo simulator.
216 Thread.sleep(1000);
217
218 // finish, close connection
219 out.close();
220 con.close();
221
222 // inform user the operation completed
223 Alert alert = new Alert( "Info", "Message Sent Success", null, AlertType.INFO );
224 alert.setTimeout( Alert.FOREVER );
225 display.setCurrent( alert, sppclientui );
226
227 } catch (Exception e)
228 {
229 e.printStackTrace();
230 showExceptionAlert( e, sppclientui );
231 }
232
233 }
234
235 /**
236 *
237 * <p>Title: DiscoveryListener implementation that handle discovery response (callback)</p>
238 * <p>Description: </p>
239 * <p>Copyright: Copyright (c) 2003</p>
240 * @author Ben Hui (www.benhui.net)
241 * @version 1.0
242 */
243 class Listener implements DiscoveryListener
244 {
245
246 /**
247 * Implements DiscoveryListener interface.
248 * This function in invoked for each RemoteDevice discovered by JABWT.
249 * See JSR-82 API spec for documentation.
250 * @param remoteDevice
251 * @param deviceClass
252 */
253 public void deviceDiscovered(RemoteDevice remoteDevice,
254 DeviceClass deviceClass)
255 {
256 log("A remote Bluetooth device is discovered:");
257 Util.printRemoteDevice( remoteDevice, deviceClass );
258
259 // store the device in the list for later use
260 devices.addElement( remoteDevice );
261 deviceClasses.addElement( deviceClass );
262
263
264 }
265 /**
266 * Implements DiscoveryListener interface.
267 * This function is invoked when the device discovery is completed.
268 * See JSR-82 API spec for documentation.
269 * @param complete
270 */
271 public void inquiryCompleted(int complete)
272 {
273 log("service discovery completed with return code:"+complete);
274 log(""+devices.size()+" devices are discovered");
275
276
277 if ( devices.size() == 0 )
278 {
279 // cannot find any Bluetooth device, tell user about this
280
281 Alert alert = new Alert( "Problem!", "No Bluetooth device found", null, AlertType.INFO );
282 alert.setTimeout(3000);
283 sppclientui.setMsg("[Press Inquiry]");
284 display.setCurrent( alert, sppclientui );
285
286 } else
287 {
288 // update the GUI list to reflect all the found devices
289 sppclientui.showui();
290 display.setCurrent( sppclientui );
291
292 }
293
294 }
295
296 /**
297 * Implements DiscoveryListener interface.
298 * This function is invoked when services are found on a RemoteDevice.
299 * See JSR-82 API spec for documentation.
300 * @param transId
301 * @param records
302 */
303 public void servicesDiscovered(int transId, ServiceRecord[] records)
304 {
305 log("Remote Bluetooth services is discovered:");
306 for ( int i=0; i< records.length; i ++ )
307 {
308 ServiceRecord record = records[i];
309 Util.printServiceRecord( record );
310 // store the service records in list for later use
311 services.addElement( record );
312 }
313 }
314
315 /**
316 * Implements DiscoveryListener interface.
317 * This function is invoked when service discovery is completed on a RemoteDevice.
318 * See JSR-82 API spec for documentation.
319 * @param transId
320 * @param complete
321 */
322 public void serviceSearchCompleted(int transId, int complete)
323 {
324 log("service discovery completed with return code:"+complete);
325 log(""+services.size()+" service are discovered");
326
327 if ( services.size() > 0 )
328 {
329 // found at least one service. since we search for SerialPort
330 // service, so we can send a message to this service using SPP connection
331 doSSPSentMessage( inputmsgui.getString() );
332
333 } else
334 {
335 // no service record found for SerialPort
336 sppclientui.showui();
337 display.setCurrent( sppclientui );
338
339 }
340
341 }
342
343 } // Listener
344
345 } |
| Java2html
|
|
|
|
Benhui.net news
|
| Feb 14, 2004 - New downloads from our Bluetooth section. BlueChat example application with full source code. Learn more! Bluetooth more! [more] |
| Feb 14, 2004 - Found out what SonyEricsson P900 has to offer for J2ME developers. Review our P900 developer review. [more] |
| Feb 14, 2004 - Check out Ben's latest Java Bluetooth development article at JDJ Feb issue. Get it off the shelf while it last. [more] |
| Dec 15, 2003 - Our Bluetooth section open! Check out our Bluetooth Browser, Code gallery, and tons of links. [more] |
| Nov 08, 2003 - Join us to chat with Michael Yuan. Learn more about Enterprise J2ME. [more] |
| Nov 08, 2003 - 35 more links added to our popular J2ME Master Links [more] |
| Nov 08, 2003 - MIDP 2.0 phone list is updated to include the latest and greatest phones. And with links, too! Check it out. [more] |
| Sept 21, 2003 - Add MIDP 2.0 phone list section. [more] |
| Aug 28, 2003 - Spy your mobile device even more with our Mobile Speed tool. [more] |
| Aug 22, 2003 - Spy your mobile device with our new Mobile Echo tool. [more] |
| Aug 22, 2003 - A new forum section is added to our links database. Questions? Dunno where to start? Start from here! |
| Aug 22, 2003 - Another 20 links added to our database. You have links to suggest? email us! |
|
Aug 01, 2003 - the new benhui.net goes live! Fully updated with lots of J2ME links, UML diagrams, and special features.
|
| Aug 01, 2003 - check out our latest featured phone - Nokia 3650 [more] |
|