Java ME 장치에서 블루투스 애플리케이션을 구현할 때 처음 수행하는 단계 중 하나가 검색 프로세스입니다. 요컨대 검색 프로세스는 블루투스 사용 장치끼리 서로 찾은 다음 핸드쉐이크를 통해 각각 지원할 수 있는 서비스를 찾아내는 프로세스입니다. 이렇게 페어 연결된 장치 간에 데이터를 전송하는 방법을 알아내는 것이 그 다음 단계입니다.

이번 테크팁에서는 장치와 서비스를 검색한 다음 발견한 장치 중 하나에 사용자가 간단한 노트를 보낼 수 있게 하는 MIDlet을 만드는 방법을 소개합니다. 필자는 이 MIDlet이 Nokia N95 장치에서 작동하고 블루투스 지원이 활성화된 Windows Vista 컴퓨터에 연결되는 것을 테스트하고 확인했습니다.

전체 프로세스를 다음과 같은 단계로 나누어 봤습니다.

  1. 검색 프로세스를 시작합니다.
  2. 검색 프로세스에서 발견한 장치를 대상으로 지원되는 서비스를 쿼리합니다.
  3. 지원되는 서비스 URL을 사용하여 OBEX 데이터 교환을 시작하고 처리합니다.
지금부터 이 단계들을 자세히 설명하겠습니다. 이 MIDlet의 전체 소스 코드를 함께 참조하면서 각 단계의 코드 일부를 따라하면 효과적일 것입니다. 소스 코드는 리소스에서 압축 파일로 제공됩니다.


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" 카테고리의 다른 글

2009/05/22 11:26 2009/05/22 11:26

TRACKBACK :: http://blog.sdnkorea.com/blog/trackback/782

댓글을 달아 주세요

[로그인][오픈아이디란?]

◀ Prev 1  ... 91 92 93 94 95 96 97 98 99  ... 806  Next ▶