Java ME 장치에서 블루투스 애플리케이션을 구현할 때 처음 수행하는 단계 중 하나가 검색 프로세스입니다. 요컨대 검색 프로세스는 블루투스 사용 장치끼리 서로 찾은 다음 핸드쉐이크를 통해 각각 지원할 수 있는 서비스를 찾아내는 프로세스입니다. 이렇게 페어 연결된 장치 간에 데이터를 전송하는 방법을 알아내는 것이 그 다음 단계입니다.
이번 테크팁에서는 장치와 서비스를 검색한 다음 발견한 장치 중 하나에 사용자가 간단한 노트를 보낼 수 있게 하는 MIDlet을 만드는 방법을 소개합니다. 필자는 이 MIDlet이 Nokia N95 장치에서 작동하고 블루투스 지원이 활성화된 Windows Vista 컴퓨터에 연결되는 것을 테스트하고 확인했습니다.
전체 프로세스를 다음과 같은 단계로 나누어 봤습니다.
- 검색 프로세스를 시작합니다.
- 검색 프로세스에서 발견한 장치를 대상으로 지원되는 서비스를 쿼리합니다.
- 지원되는 서비스 URL을 사용하여 OBEX 데이터 교환을 시작하고 처리합니다.
1단계: 검색 프로세스를 시작합니다.
검색 프로세스는 로컬 블루투스 스택에게 가까운 곳에서 페어 연결이 가능한 블루투스 장치를 찾도록 지시할 때 사용됩니다. MIDlet의 경우 이 스택은 장치 공급자가 JSR 82용으로 제공하는 구현일 것입니다.
다음 코드에서 볼 수 있듯이, 로컬 장치에 있는 검색 에이전트가 이 검색 프로세스를 시작합니다.
// get the local discovery agent
agent = LocalDevice.getLocalDevice().getDiscoveryAgent();
// start the inquiry for general unlimited inquiry
agent.startInquiry(DiscoveryAgent.GIAC, this);
검색 프로세스를 시작한 검색 에이전트는 DiscoveryListener 인터페이스를 구현하는 클래스에 대해 다양한 콜백 메소드를 호출합니다. 여기서는 바로 MIDlet 클래스입니다.
구체적으로 말하자면, 이 인터페이스의 메소드 네 개를 구현해야 하는데, 그 중 두 개가 검색 단계와 관련 있습니다. 즉, deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)와 inquiryCompleted(int discType)입니다. 이 두 메소드는 각각 장치 검색과 검색 프로세스 완료를 처리합니다. 다음 MIDlet 코드에서 볼 수 있듯이, 발견된 장치에 UI를 추가할 때와 프로세스가 완료될 때 이 메소드를 사용합니다.
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
try {
// add the devices using the friendly names
listofDevices.append(btDevice.getFriendlyName(false), null);
// add to the devices hashtable
devices.put(new Long(listofDevices.size()), btDevice);
} catch(Exception ex) { handleError(ex); }
}
2단계: 검색한 장치에 대한 서비스 검색을 시작합니다.
이 팁에서는 MIDlet에서 호환 장치로의 데이터 전송을 가능하게 하는 것이 목적이므로, 이 목표를 실현할 서비스를 검색된 장치에서 찾아야 합니다. 그러기 위해서는 서비스 검색 프로세스에서 올바른 속성과 UUID를 지정해야 합니다. 다음 코드에서 그 방법을 보여 줍니다.
agent.searchServices(
null,
new UUID[] {new UUID(0x1105L)}, // we want the OBEX PUSH Profile
device,
this);
짐작하시다시피, 이 코드에서는 앞서 장치 검색에 사용했던 로컬 에이전트를 사용합니다. 특정 속성 집합을 찾는 것이 아니므로, 첫 번째 매개 변수로 null을 전달하지만, UUID는 OBEX PUSH 프로필이 되어야 합니다. 데이터를 전달하는 가장 개방적인 방법이기 때문입니다.
DiscoveryListener 인터페이스에 대해 언급했는데, 이 인터페이스의 다른 두 메소드는 검색된 서비스를 적용하는 데 사용할 수 있습니다. 두 메소드는 바로 servicesDiscovered(int transID, ServiceRecord[] servRecord)와 serviceSearchCompleted(int transID, int respCode)입니다. 이름에서도 알 수 있듯이, 첫 번째 메소드는 서비스를 검색할 때마다 호출되고 두 번째 메소드는 서비스 프로세스를 완료할 때 호출됩니다.
서비스를 검색할 때마다 해당 장치에서 그 서비스에 대한 연결 URL을 찾아야 합니다. 이 연결 URL은 데이터를 전달할 OBEX 연결 설정에 쓰이며, 해당 장치의 블루투스 하드웨어 주소로 구성됩니다. 아래 코드에서는 servicesDiscovered 메소드에서 이 연결 URL을 가져옵니다.
String connURL = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
이제 이 연결 URL을 사용하여 검색된 장치로 데이터를 전송하는 프로세스로 진행할 수 있습니다.
3단계: OBEX PUT을 사용하여 데이터를 보냅니다.
이 MIDlet에서는 사용자가 노트와 같은 텍스트를 입력한 다음 검색된 장치/서비스를 통해 그 텍스트를 전송할 수 있게 하려고 합니다. 이를 위해 이전 단계에서 얻은 연결 URL과 String 형식의 노트 데이터가 필요합니다.
// open a client session
ClientSession clientSession =
(ClientSession) Connector.open(connURL);
// connect using no headers
clientSession.connect(null);
if(rHeaders.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
// the connection could not be established
handleError(
new Exception("Remote client returned invalid response code: " +
rHeaders.getResponseCode()));
return;
}
// if we are here, then response code was ok
// create a new set of headers
HeaderSet headers = clientSession.createHeaderSet();
headers.setHeader(
HeaderSet.LENGTH,
new Long(noteBox.getString().length()));
headers.setHeader(HeaderSet.NAME, "myNote.txt");
headers.setHeader(HeaderSet.TYPE, "text/plain");
// create an operation using the headers we have just created
Operation op = clientSession.put(headers);
// on this operation, create the output stream
OutputStream out = op.openOutputStream();
// and send the note
out.write(noteBox.getString().getBytes());
데이터를 보내기 위해 클라이언트 세션이 열리고 빈 헤더로 연결이 설정됩니다. 여기서 대상 장치는 새 장치의 데이터 수신 확인을 요청합니다. 또한 이전에 그 장치와 페어 연결한 적이 없는 경우 패스키를 입력하라고 할 수도 있습니다.
연결이 설정되면 데이터 용도를 설명하는 헤더가 생성되고 이 헤더와 함께 새 Operation이 생성됩니다. 그런 다음 이 Operation은 사용 가능한 OutputStream을 통해 데이터를 보낼 때 사용됩니다.
수신된 노트는 대상 장치의 기본 블루투스 교환 폴더에 있습니다.
자료
소스 코드 - Netbeans 프로젝트
Bluetooth JSR 82 API
저자 : Vikram Goyal
이 글의 영문 원본은
Discovering Devices and Sending Files via Bluetooth in Java ME
에서 보실 수 있습니다.
"Java ME" 카테고리의 다른 글
- 블루투스와 GPS 사용: 1부 - 무선 직렬 포트 데이터 읽기 (댓글 0개 / 트랙백 0개) 2008/08/11
- 서비스 지향 아키텍처 및 자바 ME (댓글 7개 / 트랙백 0개) 2007/04/10
- destroyApp()는 당신의 친구 (댓글 0개 / 트랙백 0개) 2009/09/28
- 자바 ME 장치 매트릭스로 필터 사용 (댓글 0개 / 트랙백 0개) 2008/03/13
- Java ME를 사용한 블루레이 디스크 애플리케이션 개발 제 1 부: 나만의 애플리케... (댓글 0개 / 트랙백 0개) 2008/10/13
- 모바일 플랫폼의 비교: Java ME와 Adobe Flash Lite (댓글 0개 / 트랙백 1개) 2008/06/03
- NetBeans Mobility Pack 5.0 입문을 위한 속성 가이드 (댓글 5개 / 트랙백 0개) 2006/09/26
- 모바일 자바 플랫폼의 현재와 미래 (댓글 5개 / 트랙백 1개) 2006/07/26
- MIDlet의 로깅과 모니터링을 위한 간단한 전략 (댓글 0개 / 트랙백 0개) 2009/10/22
- 아프리카에서 전하는 소식: 이 지역에서 자바 ME 플랫폼에 주어진 과제와 기회 (댓글 0개 / 트랙백 0개) 2008/12/16
댓글을 달아 주세요