Все необходимые действия по регистрации сервиса берет на себя Java Bluetooth API. Вызов метода Connector.open() автоматически задает сервисную запись. Затем вызывается метод StreamConnectionNotifier.acceptAndOpen() или L2CAPConnetionNotifier.acceptAndOpen(), который добавляет ее в Service Discovery Database (SDDB). С этого момента устройство может подключаться к другим устройствам и отвечать на попытки подключений клиентов.
Процесс поиска доступных по Bluetooth устройств и сервисов является, пожалуй, наиболее сложной частью Java APIs for Bluetooth. API для поиска устройств включает в себя класс DiscoverAgent и интерфейсы DiscoveryListener, RemoteDevice, ServiceRecord.
JSR-82 совместимый мидлет использует DiscoveryAgent, который предоставляет методы, позволяющие осуществлять поиск устройств и сервисов. Мидлет должен использовать интерфейс DiscoveryListener, для того чтобы узнать о найденном устройстве. Чтобы получить DiscoveryAgent устройства, необходимо вызвать метод LocalDevice.getDiscoveryAgent().
Мидлет начинает фазу поиска с вызова метода DiscoveryAgent.startInquiry(), который переводит устройство в режим "запроса". Как только устройство или сервис будут найдены, DiscoveryAgent уведомит об этом мидлет, вызвав callback методы deviceDiscovered() и servicesDiscovered(). Поскольку выполнение запросов требует времени, перед инициализацией режима запроса, мидлет обычно вызывает методы retrieveDevices() и searchServices() класса DiscoveryAgent, чтобы произвести поиск в локальногм кэше обнаруженных ранее устройств и сервисов. На следующей диаграмме показана последовательность действий при поиске.
DiscoveryAgent предоставляет методы для поиска устройств и сервисов:
DiscoveryListener предоставляет callback функции, которые вызываются, если найдено устройство или сервис:
ServiceRecord описывает удаленный сервис или RemoteDevice. Он предоставляет методы для получения атрибутов сервиса, его URL, host удаленного устройства и изменения Service Discovery Database:
Приведенный ниже пример демонстрирует использование Discovery API.
Listing 8. Пример использования Discovery API.
public class MyMIDlet implements DiscoveryListener {
LocalDevice localDevice= LocalDevice.getLocalDevice(); DiscoveryAgent discoveryAgent= localDevice.getDiscoveryAgent(); RemoteDevice[] devList; Vector deviceList=new Vector();// Вектор найденных устройств ServiceRecord serviceRecord; : : //** Вспомогательный метод реализующий начало фазы поиска удаленных устройств и сервисов */ private void discover(){ //Устройства, найденные в предыдущем запросе. devList= discoveryAgent.retrieveDevices(DiscoveryAgent.CACHED); if(devList!=null){ serviceRecord= searchServices(devList); if(serviceRecord==null){ // Получаем предопределенные устройства . devList= discoveryAgent.retrieveDevices(DiscoveryAgent.PREKNOWN); if(devList!=null){ serviceRecord= searchServices(devList); } } } if(serviceRecord==null){ serviceAgent.startInquiry(DiscoveryAgent.GIAC, this); } } /* Поиск интересующих нас сервисов на удаленном устройстве*/ private boolean searchServices(RemoteDevice[] devList){ UUID[] searchList=new UUID[2]; // Добавляем UUID для L2CAP, чтобы убедиться в том, // что найденная сервисная запись поддерживает L2CAP. // Это значение определено в Bluetooth Assigned Numbers document. searchList[0]=new UUID(0x0100); // Добавляем UUID для интересующего нас сервиса searchList[1]=new UUID(MY_SERVICE_UUID,false); // Ищем список устройств, поддерживающих интересующий нас сервис. for(int i=0; i< devList.length; i++){ try{ int trans; trans= discoveryAgent.search Services(null, searchList, devList[i], this); } catch(BluetoothStateException e){ } } } //*********************************/ //** DiscoveryListener Callbacks **/ //*********************************/ //** Вызывается, когда будет найден сервис*/ public void servicesDiscovered(int transID, ServiceRecord[] servRecord){ if(serviceRecord!=null)return; // Сервис найден. Используем первый попавшийся. serviceRecord= servRecord[0]; } //** Вызывается, когда обнаружено устройство*/ public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod){ deviceList.addElement(btDevice);// Сохраняем устройство } //** Вызывается при завершении поиска сервиса*/ public void serviceSearchCompleted(int transID, int respCode){ : } //** Вызывается при завершении фазы запроса*/ public void inquiryCompleted(int discType){ : } }
Java API for Bluetooth поддерживает защищенное соединение. Серверное соединение может быть классифицировано, как безопасное перед или после его установки.
Чтобы определить соединение как защищенное до фактического соединения, необходимо задать URL, содержащий параметры безопасности. В приведенном ниже примере создается защищенное RFCOMM серверное соединение, которое поддерживает авторизацию и шифрование.
String url = "btspp://localhost:3B9FA89520078C303355AAA694238F07; authenticate=true;encrypt=true";
Чтобы изменить настройки безопасности для уже установленного соединения, надо использовать методы класса RemoteDevice:
Чтобы определить, является ли соединение защищенным, используйте следующие методы класса RemoteDevice:
Клиент может получить информацию о состоянии авторизации и шифрования из параметров URL строки соединения метода Connector.open(). Кроме того, если клиент подключился к удаленному сервису, он может воспользоваться методом ServiceRecord.getConnectionURL(), чтобы получить атрибуты из URL удаленного сервиса:
В приведенном ниже куске кода показано, как использовать getConnectionURL() для получения URL соединения с заданными параметрами безопасности.
ServiceRecord serviceRecord; : : // Как только получите ServiceRecord удаленный сервис, используйте // getConnectionURL для получения URL. String url= serviceRecord.getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT, false);
Другими словами, JSR-82 совместимый мидлет должен быть помечен как доверенный, чтобы обратиться к стеку Bluetooth телефонной трубки.
Вместе с этой статьей распространяется демонстрационноеприложение.
Приложение написано для телефона Sony Ericsson P900, или любого другого, оснащенного сенсорным экраном и Bluetooth. После запуска программ и соединения Вы попадаете в простой графический редактор, причем рисовать в нем могут оба участника одновременно. Иконка в левом верхнем углу экрана сигнализирует о состоянии соединения.
Прежде чем запускать приложение, убедитесь, что ваш Bluetooth адаптер включен.
Bluepad - это демонстрационное приложение, написанное на J2ME MIDP 2.0 с использованием JSR-82 Bluetooth API.
Эта статья является переводом документа Developing Applications with the Java APIs for Bluetooth™ (JSR-82), найденного на сайтеhttp://developer.sonyericsson.com
Перевод:aRix.