📄 btutil.java
字号:
/** * Register into BtUtil API a new object interested in receveing bluetooth * client related notifications, i.e. "device discovered!", * "device discovery finished!", "service discovered!", * "service discovery finished!". * * @param BtUtilClientListener The object to be registered. */ public void addBtUtilClientListener(BtUtilClientListener l) { out.println("[BtUtil API] New BtUtilClientListener registered."); //Only for safety if (clientListeners == null) { clientListeners = new Vector(); } clientListeners.addElement(l); } /** * Create a new bluetooth service with the specified UUID. <p/> * This method will block all the execution, waiting for connections. * If you don't want that, call it from a new thread. Ex: <p/> * * Thread t = new Thread() { <br/> * public void run() { <br/> * try { <br/> * btUtil.startStreamService(SERVICE_UUID, me); <br/> * } catch (BtUtilException ex) { <br/> * out.println(ex.toString()); <br/> * } <br/> * } <br/> * }; <br/> * * t.start(); * * @param uuid The service UUID, in hexadecimal format. * Example: Use "ABCD" instead of "0xABCD". */ public void startStreamService(String uuid, BtUtilServerListener listener) throws BtUtilException { //Create the default service URL. String serviceUrl = getDefaultSPPUrl(uuid); //The service handle StartedStreamService service = null; //Store the service listener for future notifications, when a new connection arrives. if (startedStreamServices.containsKey(serviceUrl) && startedStreamServices.get(serviceUrl) != null) { //The service already has some listeners. out.println("[BtUtil API] Service [" + serviceUrl + "] has " + ((StartedStreamService)startedStreamServices.get(serviceUrl)).getListeners().size() + " listeners."); } else { //The service has no listeners yet. out.println("[BtUtil API] Service [" + serviceUrl + "] has no listeners yet."); //So, create a new listener list for it. startedStreamServices.put(serviceUrl, new StartedStreamService()); } service = (StartedStreamService)startedStreamServices.get(serviceUrl); //Finally, add the listener passed as argument to the service listener list. service.addListener(listener); //Open the server connection and wait... try { StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open(serviceUrl); //Hold the service notifier to stop it later. service.setNotifier(notifier); //Watch out to not make confusion betwenn startedStreamServices //and serviceListeners variables. Vector serviceListeners = null; //A service is said to be in the "running" state while there's //listeners for its server connections. When the startStreamService //is called, at least one listener is stored for that service. //On the other side, when the stopStreamService method is called, //every listener for that service is removed and then, it's said //to be stopped. while (isServiceRunning(serviceUrl)) { out.println("[BtUtil API] Waiting for SPP connections..."); final StreamConnection conn = (StreamConnection)notifier.acceptAndOpen(); out.println("[BtUtil API] SPP Connection established!!!!"); //Check if the service is still up and running if (!startedStreamServices.containsKey(serviceUrl)) { //The service is not running anymore. throw new BtUtilException("The service [" + serviceUrl + "] " + "cannot accept new connections because it's not running."); } out.println("[BtUtil API] Notifying BtUtilServerListener listeners..."); serviceListeners = service.getListeners(); for (int i = 0; i < serviceListeners.size(); i++) { out.println("[BtUtil API] Notifying BtUtilServerListener #" + i + "..."); //Each notification will be held on its own thread. final BtUtilServerListener l = (BtUtilServerListener)serviceListeners.elementAt(i); Thread t = new Thread() { public void run() { l.connectionEstablished(conn); } }; t.start(); } out.println("[BtUtil API] BtUtilServerListener listeners notified."); } } catch (IOException e) { String msg = "Could not start service [" + serviceUrl + "]. " + e; out.println(msg); throw new BtUtilException(msg); } } /** * Stop the service execution with the given UUID. * @param uuid The UUID whose service should be stopped. * @throws BtUtilException If the service specified is not running. */ public void stopStreamService(String uuid) throws BtUtilException { //Create the default service URL. String serviceUrl = getDefaultSPPUrl(uuid); if (!isServiceRunning(serviceUrl)) { throw new BtUtilException("Service [" + serviceUrl + "] " + "cannot be stopped because it's not running."); } out.println("[BtUtil API] Stopping service [" + serviceUrl + "]..."); StartedStreamService service = (StartedStreamService)startedStreamServices.get(serviceUrl); try { //The notifier object was kept to be used at this point. service.getNotifier().close(); } catch (IOException e) { String msg = "[BtUtil API] The service " + uuid + " could not be stopped. " + e; out.println(msg); throw new BtUtilException(msg); } startedStreamServices.remove(serviceUrl); out.println("[BtUtil API] Service [" + serviceUrl + "] stopped."); //TODO There's a problem here. When I remove all the service listeners, //the service is still blocked on a acceptAnOpen call. That's mean, //the service thread will be still there, even after a stopStreamService //invokation. How to close the StreamConnectionNotifier? } /** * Test if the specified bluetooth service exist. * * @param device The bluetooth device where the service is supposed to be running. * Use the discoverDevicesSync method to get a list of * devices in the neighboorhood. * * @param serviceUUID The supposed bluetooth service UUID, in hexadecimal format. * Example: Use "ABCD" instead "0xABCD". * * @return true if the specified service exist, false otherwise. */ public boolean hasService(RemoteDevice device, String serviceUUID) throws BtUtilException { String serviceUUDIHex = "0x" + serviceUUID; out.println("[BtUtil API] Going test service [" + serviceUUDIHex + "] existence."); if (device == null) { out.println("[BtUtil API] A null device don't have any sevice. I'm sure."); } Vector services = discoverServicesSync(device, new String[] {serviceUUID}); if (services == null || services.size() == 0) { out.println("[BtUtil API] No service found with UUID [" + serviceUUDIHex + "]."); return false; } out.println("[BtUtil API] " + services.size() + " services found with UUID [" + serviceUUDIHex + "]."); return true; } /** * Test if the specified bluetooth service exist. If any error ocurs while * connecting to the service (and it happens very often), try some more * times. * * @param device The bluetooth device where the service is supposed to be running. * Use the discoverDevicesSync method to get a list of * devices in the neighboorhood. * * @param serviceUUID The supposed bluetooth service UUID, in hexadecimal format. * Example: Use "ABCD" instead "0xABCD". * * @param tries The maximum tries allowed, in case of service communication error. * @param listener An object that will be notified each time a new try * is started. If you don't want to receive these notifications, let it null. * * @return true if the specified service exist, false otherwise. */ public boolean hasService(RemoteDevice device, String serviceUUID, int tries, BtUtilClientListener listener) throws BtUtilException { out.println("[BtUtil API] Trying " + tries + " times to find service 0x" + serviceUUID); int counter = 1; boolean hasService = false; boolean testSuccessful = false; //While you cannot check the service existence and you have not spent //all oportunities to do that, try again. while ( !(testSuccessful && hasService) && counter <= tries) { try { //Notify listener the try #counter is about to start. if (listener != null) {listener.tryingAgain(counter);} //Test the service existence. out.println("[BtUtil API] Trying #" + counter + " to find service 0x" + serviceUUID); hasService = hasService(device, serviceUUID); out.println("[BtUtil API] Service test #" + counter + " finished. Service found? " + hasService); testSuccessful = true; counter++; } catch (BtUtilException e) { //If some error occurs, try again, up to "tries" more times. if (counter < tries) { out.println("[BtUtil API] Failed to find service. Let's try " + (tries-counter) + " more times."); counter++; } else { out.println("[BtUtil API] Failed again to find service 0x" + serviceUUID + ". I'll give it up."); } } } out.println("[BtUtil API] Service existing test finished in " + (counter-1) + " tries."); return hasService; } /** * Get the device friendly name. * @param device The device whose friendly name will be gotten. * @return The device friendly name or "Unknown" if its name cannot be recovered. */ public String getDeviceName(RemoteDevice device) { String deviceName = null; try { deviceName = device.getFriendlyName(true); } catch (IOException ex) { deviceName = "Unknown"; } return deviceName; } /** * Reset the bluetooth stack. */ private void resetBluetoothStack() { localDevice = null; agent = null; } /** * Initialize the bluetooth stack. */ private void initBluetoothStack() throws BtUtilException { out.println("[BtUtil API] Initializing the bluetooth stack..."); try { out.println("[BtUtil API] Getting local device reference..."); localDevice = LocalDevice.getLocalDevice(); out.println("[BtUtil API] Setting local device discoverability..."); localDevice.setDiscoverable(DiscoveryAgent.GIAC); out.println("[BtUtil API] Getting discovery agent reference..."); agent = localDevice.getDiscoveryAgent(); } catch (Exception e) { e.printStackTrace();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -