메뉴 건너뛰기

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

단축키

Prev이전 문서

Next다음 문서

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

단축키

Prev이전 문서

Next다음 문서

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

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

 

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

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

 

 클래스 이름

 설명

 BluetoothAdapter

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

 BluetoothDevice

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

 BluetoothSocket

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

 BluetoothServerSocket

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

 


블루투스 장치 켜기 


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


List of Articles
번호 제목 날짜 조회 수
117 안드로이드 종료 취소 다이얼로그 코드 2015.07.26 6448
116 폰갭 비콘 디텍팅 안될 때 (기본적인건 다 되있어야됨) 2015.07.26 6584
115 안드로이트 비콘 스캐닝시 고려 사항 2015.07.26 6724
114 블루투스 및 비콘 관련 정리 2015.07.26 10886
» 블루투스(Bluetooth) 통신에 대해 알아보자 file 2015.07.26 14118
112 안드로이드 팝업창 만들기(xml 내용 집어넣기) file 2015.07.23 9363
111 안드로이드 스튜디오 gradle error 해결 2015.07.23 6748
110 [안드로이드] 화면추가 버튼 리스너 file 2015.07.22 7754
109 [안드로이드] 페이스북 같은 슬라이드 메뉴 만들기 file 2015.07.21 8277
108 안드로이드 ( Android ) APK 파일 생성하기 file 2015.07.17 7367
107 안드로이드 webview (웹뷰) 개발 #4 - 멀티터치 ( 확대 / 축소 ) 적용 file 2015.07.17 7607
106 안드로이드 webview (웹뷰) 개발 #3 - 초기 로딩화면 (splash) 띄우기 + 아이콘 적용하기 file 2015.07.17 8753
105 안드로이드 webview (웹뷰) 개발 #2 - 파일 첨부 및 플러그인 적용하기 file 2015.07.17 8347
104 안드로이드 webview (웹뷰) 개발 #1 - 웹사이트를 어플로 만들어 보자! file 2015.07.17 8967
103 [안드로이드] 버튼 이벤트 처리하기 file 2015.07.17 7103
102 [안드로이드] 뷰(View)에 여백넣기 file 2015.07.17 7295
101 [안드로이드] 뷰(View)의 너비와 높이 지정하기 file 2015.07.17 7215
100 [안드로이드] 레이아웃의 기본2 file 2015.07.16 7141
99 [안드로이드] 레이아웃의 기본1 file 2015.07.16 7024
98 [안드로이드] Activity에 대해서 file 2015.07.16 6825
Board Pagination Prev 1 ... 3 4 5 6 7 8 9 10 11 12 13 Next
/ 13

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved