메뉴 건너뛰기

조회 수 7982 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

안드로이드에서 블루투스를 통해 단말 간 데이터를 주고받기 위해 필요한 과정은 다음과 같습니다

 

  1. 내 블루켜스 켜기
  2. 다른 블루투스 검색하기
  3. 다른 블루투스 단말과 페이링하기
  4. 다른 블루투스 단말에 연결하기
  5. 데이터 주고 받기

안드로이드에서 지원하는 블루투스는 android.bluetooth 패키지에 들어 있는 클래스들을 이용하게 되는데 주요 클래스들은 다음과 같습니다

 

 클래스 이름

 설명

 BluetoothAdapter

 블루투스 장치를 제어하기 위해 참조하는 객체로 이를 이용해 시스템 서비스로 제공되는 블루투스 서비스를 사용할 수 있음 

 BluetoothDevice

 다른 블루투스 디바이스를 나타내는 객체로 다른 디바이스에 연결을 요구하거나 다른 디바이스의 상태 정보를 확인할 수 있음 

 BluetoothSocket

 데이터를 주고받기 위해 사용되는 소켓 객체임

 BluetoothServerSocket

 데이터를 주고받기 위해 사용되는 서버소켓 객체임

 


블루투스 장치 켜기 

1.png



다음은 BluetoothChat 애플리케이션을 실행하였을 때 장치를 켜는 화면입니다

2.png



위 화면에서 사용자가 [예] 버튼을 누르면 '블루투스를 켜는 중'이라는 메시지가 보이고 블루투스 장치를 켜는 과정이 끝나면 원래의 메인 액티비티가 보이게 됩니다


메인 액티비티가 나타날 때 응답 데이터를 보내주게 되면 onActivityResult() 메서드를 재정의하여 처리하면 되는데. 다음 코드에서는 장치를 켜기 위한 시스템 액티비티에서 보내온 응답을 처리하고 있습니다

3.png



만약 애플리케이션에서 장치를 켜기 위한 과정을 진행하지 않고 단말의 설정을 이용해서 블루투스 장치를 켜거나 할 때 애플리케이션에서 응답을 받아 처리하려면 어댑터 클래스 ACTION_STATE_CHANGED 액션으로 만들어진 인텐트를 브로드캐스트 수신자로 받아 처리하면 됩니다


다른 블루투스 검색하기, 검색 과정을 진행하기 위해서는 먼저 디바이스가 검색 가능한 상태로 되어 있어야 (Discoverable) 검색 요청에 응답할 수 있습니다. 검색 가능한 상태를 만들기 위해서는 다음과 같은 코드가 사용됩니다

4.png



어댑터 클래스에 정의된 getScanMode() 메서드를 이용하면 내 블루투스 디바이스가 검색 가능한 상태인지 확인할 수 있습니다. ACTION_REQUEST_DISCOVERABLE 액션은 검색 가능한 상태로 만들어주기 위한 시스템 액티비티를 띄우기 위해 정의된 상수입니다


인텐트의 부가정보로 설정하는 EXTRA_DISCOVERABLE_DURATION의 값은 디바이스가 얼마동안 검색 가능한 상태로 있을 것인지를 알려줍니다. 디폴트 값은 120초이지만 최대 300초까지 시간을 늘릴 수 있습니다


다음은 이렇게 내 블루투스 디바이스를 검색 가능한 상태로 만들 때 보이는 시스템 액티비티 화면입니다

5.png



만약 내 단말에서 다른 단말로 연결하고자 하는 경우에는 일부로 내 단말을 검색 가능한 상태로 만들 필요는 없습니다


블루투스 디바이스를 검색하기 전에 이미 페이링된 디바이스가 있는지 확인해볼 수 있습니다. 페어링(Paired)은 두 개의 블루투스 디바이스가 서로의 정보를 알고 있고 인증에 사용되는 lint-key를 공유하고 있어 암호화된 연결이 가능한 상태를 의미합니다. 블루투스는 RFCOMM이라는 연결을 설정하기 전에 디바이스끼리 페이링되어 있어야 하는데. 안드로이드의 블루투스 API를 사용할 때는 연결을 시작할 때 자동으로 페어링 과정이 진행됩니다


예제 소스의 [Connect a device] 버튼을 누르면 디바이스 검색을 위한 액티비티를 띄우게 되는데 디바이스 검색 액티비티의 코드는 다음과 같습니다

6.png



위 소스의 getBondedDevices() 메서드는 페어링된 디바이스 정보를 BluetoothDevice 객체로 만들어 Set 객체에 추가한 후 리턴합니다. 만약 블루투스 장치의 상태가 STATE_ON이 아닌 경우에는 널값을 리턴할 수도 있습니다. 페이링된 디바이스 정보가 하나라도 있으면 BluetoothDevice 객체의 이름과 MAC 주소를 문자열로 만들어 리턴합니다


이제 디바이스를 직접 검색하는 코드는 다음과 같습니다

7.png



블루투스 어댑터 객체의 startDiscovery() 메서드를 호출하여 디바이스 검색을 시작합니다. 만약 이미 검색중이라면 cancelDiscovery() 메서드를 호출하여 검색을 멈춘 후 다시 검색해야 합니다. 디바이스가 찾아졌을 때(ACTION_FOUND)와 검색과정이 끝났을 때(ACTION_DISCOVERY_FINISHED) 인텐트를 전달받기 위해 두 개의 인텐트 필터를 등록합니다


인텐트 필터를 등록할 때 파라미터로 전달된 브로드캐스트 리시버는 다음과 같이 정의되어 있습니다

8.png



이제 리스트 뷰에 검색된 디바이스들이 나타나게 되는데 그 실행 화면은 다음과 같습니다

9.png



디바이스가 검색되면 그 중의 하나를 터치하여 연결하게 됩니다. 리스트뷰의 한 아이템을 터치하였을 때 메인 액티비티로 돌아가는 코드는 다음과 같습니다

10.png



메인 액티비티에서 선택한 디바이스로 연결을 시도할 것이므로 MAC 주소를 부가정보로 추가한 인텐트 객체를 만들어 응답을 보내게 됩니다


다음은 메인 액티비티에서 응답을 받은 후 BluetoothDevice 객체를 만들어 선택한 디바이스로 연결하는 코드입니다

11.png



블루투스 어댑터 클래스의 getRemoteDevice() 메서드는 MAC 주소를 이용해 BluetoothDevice 객체를 만들어줍니다. 이 객체를 이용해 BluetoothService 클래스에 정의된 connect() 메서드를 호출하면 ConnectThread를 만들어 연결을 시도하게 됩니다

12.png



두 개의 블루투스 디바이스가 데이터를 주고 받기 위해서는 RFCOMM 채널 위에서 클라이언트 소켓과 서버 소켓이 연결되어야 합니다. 클라이언트 소켓 객체는 BluetoothDevice 클래스에 정의되어 있는 createRfcommSocketToServiceRecord() 메서드를 호출하면 만들 수 있습니다. 이 때 전달되는 UUID 파라미터는 서버 소켓에서도 동일한 값을 사용해야 합니다. connect() 메서드는 서버 소켓으로 연결을 시도하고 일정 시간동안 연결되지 않으면 Timeout 예외를 발생시킵니다. 소켓 연결을 통해 데이터를 주고 받은 후 종료할 때는 항상 close() 메서드를 호출합니다


서버 소켓listenUsingRfcommWithServiceRecord() 메서드를 이용해 만들 수 있으며, accept() 메서드를 호출하여 대기하다가 클라이언트 소켓이 연결을 요청하면 연결을 만든 후 클라이언트 소켓 객체를 리턴합니다

13.png



다음은 두 개의 디바이스를 연결할 것인지 물어보는 실행 화면입니다

14.png



소켓이 연결되면 데이터를 주고받을 수 있습니다. 블루투스에서 사용하는 소켓은 일반 소켓과 거의 동일한 구성을 가지고 있으므로 입력과 출력 스트림 객체를 만들어 데이터를 읽거나 쓸 수 있습니다


다음은 소켓 연결 이후에 데이터를 읽고 쓰는 방법을 보여주는 코드입니다

15.png



소켓 객체에서 만든 InputStream과 OutputStream 객체는 데이터를 읽고 쓰는데 사용됩니다. 스트림에서 읽어 들인 데이터를 화면에 표시할 때는 지금 코드 부분이 스레드 안에 들어가 있으므로 핸들러 객체를 사용해야 합니다


지금까지 살펴본 것처럼 블루투스는 소켓 연결이 만들어지면 손쉽게 데이터를 읽거나 쓸 수 있지만 소켓 연결을 만들기까지의 과정이 필요합니다. 따라서 실제 애플리케이션에 적용할 때는 다른 디바이스와의 연결 관리가 가장 중요한 부분이라 할 수 있습니다

Atachment
첨부 '32'

List of Articles
번호 제목 날짜 조회 수
157 노티피케이션(Notification) 사용법 / Notification.Builder , NotificationManager file 2016.06.10 13467
156 어댑터 뷰(Adapter View) & 어댑터(Adapter) (1) file 2016.06.08 7852
155 Activity Data Transfor/ 액티비티 이동간에 데이터 전송하기 file 2016.06.07 7676
154 Activity Switching / 안드로이드 액티비티 전환 / 화면 전환 file 2016.06.07 8311
153 알아놓으면 좋은 내용정리 2016.06.07 7458
152 간단한 mp3 플레이어 만들기 , 음악넣기 , 노래재생 file 2016.06.07 14619
151 암시적 인텐트를 사용한 인터넷열기, 전화걸기, 문자보내기 [Intent (인텐트)] file 2016.06.07 7736
150 Intent (인텐트) 2016.06.07 7626
149 Android 와 JSP 간 파라미터 암복호화 (3) file 2016.05.26 8088
148 Android 와 JSP 간 파라미터 암복호화 (2) 2016.05.26 7735
147 Android 와 JSP 간 파라미터 암복호화 (1) file 2016.05.26 7474
146 카카오톡 대화내용 가져오기(sqlite3, chat_logs) file 2016.05.26 15087
145 카카오톡 분석하기 (2) - 카카오톡 암호화 함수 찾기 file 2016.05.26 9598
144 카카오톡 분석하기 (1) - sqlite 파해치기 file 2016.05.26 10060
143 안드로이드용 채팅프로그램 클라이언트(java), 서버(c#) 소스 file 2016.05.19 11720
142 네트워크 연결 상태 및 3G/WIFI 연결상태 체크하기 2016.03.18 7131
141 Android Push GCM 프로젝트 앱 적용 하기(2) file 2016.03.18 8945
140 안드로이드] 페이스북 같은 슬라이드 메뉴 만들기 file 2015.12.15 12534
139 Android TIP] strings.xml 에서 특수문자 사용하기 2015.12.15 6629
138 Android] Fragment 내부의adapter에서 startActivity 하기 2015.12.15 6487
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved