Использование Bluetooth в J2ME приложениях. (JSR-82) - Часть 3. Device и Service Discovery API

Регистрация сервиса

Все необходимые действия по регистрации сервиса берет на себя Java Bluetooth API. Вызов метода Connector.open() автоматически задает сервисную запись. Затем вызывается метод StreamConnectionNotifier.acceptAndOpen() или L2CAPConnetionNotifier.acceptAndOpen(), который добавляет ее в Service Discovery Database (SDDB). С этого момента устройство может подключаться к другим устройствам и отвечать на попытки подключений клиентов.

Обзор Device и Service Discovery API

Процесс поиска доступных по Bluetooth устройств и сервисов является, пожалуй, наиболее сложной частью Java APIs for Bluetooth. API для поиска устройств включает в себя класс DiscoverAgent и интерфейсы DiscoveryListener, RemoteDevice, ServiceRecord.

MIDlet

JSR-82 совместимый мидлет использует DiscoveryAgent, который предоставляет методы, позволяющие осуществлять поиск устройств и сервисов. Мидлет должен использовать интерфейс DiscoveryListener, для того чтобы узнать о найденном устройстве. Чтобы получить DiscoveryAgent устройства, необходимо вызвать метод LocalDevice.getDiscoveryAgent().

Мидлет начинает фазу поиска с вызова метода DiscoveryAgent.startInquiry(), который переводит устройство в режим "запроса". Как только устройство или сервис будут найдены, DiscoveryAgent уведомит об этом мидлет, вызвав callback методы deviceDiscovered() и servicesDiscovered(). Поскольку выполнение запросов требует времени, перед инициализацией режима запроса, мидлет обычно вызывает методы retrieveDevices() и searchServices() класса DiscoveryAgent, чтобы произвести поиск в локальногм кэше обнаруженных ранее устройств и сервисов. На следующей диаграмме показана последовательность действий при поиске.

DiscoveryAgent

DiscoveryAgent предоставляет методы для поиска устройств и сервисов:

  • boolean cancelInquiry(DiscoveryListener listener) - выводит устройство из режима запроса.
  • boolean cancelServiceSearch(int transID)- отменяет транзакцию поиска сервиса, имеющую заданный ID.
  • RemoteDevice[] retrieveDevices(int option) - возвращает в зависимости от аргумента массив Bluetooth устройств, которые были найдены локальным устройствам в течение предыдущего запроса, или предопределенные устройства.
  • int searchServices(int[] attrSet, UUID[] uuidSet, RemoteDevice btDev, DiscoveryListener discListener) - производит поиск сервисов на удаленном Bluetooth устройстве, которое имеет все UUID, переданные в uuidSet.
  • java.lang.String selectService(UUID uuid, int security, boolean master) - пытается локализовать сервис, содержащий uuid в ServiceClassIDList сервисной записи.
  • boolean startInquiry(int accessCode, DiscoveryListener listener) - переводит устройство в режим запроса.


DiscoveryListener

DiscoveryListener предоставляет callback функции, которые вызываются, если найдено устройство или сервис:

  • void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) - вызывается, если в течение запроса было найдено устройство.
  • void inquiryCompleted(int discType) - вызывается, когда запрос выполнен.
  • void servicesDiscovered(int transID, ServiceRecord[] servRecord) - вызывается, если был найден сервис во время поиска сервисов.
  • void serviceSearchCompleted(int transID, int respCode) - вызывается, когда поиск сервисов выполнился, либо когда произошла ошибка.


ServiceRecord

ServiceRecord описывает удаленный сервис или RemoteDevice. Он предоставляет методы для получения атрибутов сервиса, его URL, host удаленного устройства и изменения Service Discovery Database:

  • int[] getAttributeIDs() - возвращает ID атрибута сервиса, значение которого может быть найдено с помощью метода getAttributeValue().
  • DataElement getAttributeValue(int attrID) - возвращает значение ID атрибута сервиса, либо ноль.
  • java.lang.String getConnectionURL(int requiredSecurity, boolean mustBeMaster) - возвращает строку, содержащую любые дополнительные параметры, которые клиент может использовать для соединения с сервисом, описанным ServiceRecord.
  • RemoteDevice getHostDevice() - возвращает удаленное Bluetooth устройство, которое присутствует в соответствующем атрибуте сервисной записи.
  • boolean populateRecord(int[] attrIDs) - находит значение, соединяясь с удаленным Bluetooth устройством. Возвращаемое значение содержит набор ID атрибутов сервиса, доступных на Bluetooth устройстве.
  • boolean setAttributeValue(int attrID, DataElement attrValue) - изменяет ServiceRecord, размещая пары атрибут-значение (attrID, attrValue).
  • void setDeviceServiceClasses(int classes) - используется серверным приложением, для обозначения битов главного сервисного класса, которые должны быть активизированы классом DeviceClass на сервере, когда эта сервисная запись будет добавлена в SDDB.

Приведенный ниже пример демонстрирует использование 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.authenticate() - Попытка авторизации этого (RemoteDevice) удаленного устройства.
  • remoteDevice.encrypt(con, true) - Включение/выключение режима шифрования для существующего соединения.
  • remoteDevice.authorize(con) - Определяет, разрешено ли данному удаленному устройству продолжать работать с локальным сервисом, предоставляемым Connection.

Чтобы определить, является ли соединение защищенным, используйте следующие методы класса RemoteDevice:

  • boolean isAuthenticated() - Проверяет, прошло ли удаленное устройство авторизацию.
  • boolean isAuthorized(javax.microedition.io.Connection conn) - определяет, было ли это удаленное устройство ранее авторизированно BBC локального устройства для обмена данными с сервисом, ассоциирующимся с данным устройством.
  • boolean isEncrypted() - Определяет, включен ли режим шифрования для обмена данными с RemoteDevice.
  • boolean isTrustedDevice() - Проверяет, присвоил ли BCC данному устройству статус доверенного.

Клиент может получить информацию о состоянии авторизации и шифрования из параметров URL строки соединения метода Connector.open(). Кроме того, если клиент подключился к удаленному сервису, он может воспользоваться методом ServiceRecord.getConnectionURL(), чтобы получить атрибуты из URL удаленного сервиса:

  • java.lang.String getConnectionURL(int requiredSecurity, boolean mustBeMaster) - Возвращает строку, содержащую дополнительные параметры, которые могут быть использованы клиентом для соединения с сервисом, заданным в ServiceRecord.

В приведенном ниже куске кода показано, как использовать getConnectionURL() для получения URL соединения с заданными параметрами безопасности.

ServiceRecord serviceRecord; : : // Как только получите ServiceRecord удаленный сервис, используйте // getConnectionURL для получения URL. String url= serviceRecord.getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT, false);

Другими словами, JSR-82 совместимый мидлет должен быть помечен как доверенный, чтобы обратиться к стеку Bluetooth телефонной трубки.

Bluepad - Пример 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.




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна