본문 바로가기
Programming/Android Java

블루투스의 모든 것 Bluetooth와 안드로이드

by 개Foot/Dog발?! 2014. 9. 14.

URL : http://miguelkey.blogspot.kr/2013/02/etc-bluetooth.html


.....


3. Bluetooth 통신 방법


※ Bluetooth 는 Piconet(피코넷) 기반 무선 네트워크를 제공

- 상호 독립된 통신기기들이 통신망을 이루는 무선 네트워크 기술로

   WLAN(Wireless LAN) 과는 달리 통신 기기간 사전에 네트워크 정의와 계획없이

   컨트롤 프로토콜에 의해 Master/Slave 관계를 이루며 네트워크를 형성하는 무선 통신 방법을 의미


- Bluetooth 는 piconet 방식을 이용하여 무선 네트워크 통신을 제공


- Bluetooth 는 Master 가 되면서 Slave 가 될수도 있음.


- Bluetooth 는 복수(7개 이하) 의 피코넷으로 연결된 Scatternet 이라는 무선 네트워크를 형성할 수 있음.



4. Bluetooth 검색


※ Bluetooth 검색 방법

- One-Time Discovery : 사용자가 원하는 시점에 단 한번만 검색, Battery 절감을 위해 원타임 검색을 지원

- Cyclic Discovery :  주기적으로 블루투스 기기들의 항목들을 갱신, Wifi AP 처럼 동작하는 방식


※ Bluetooth Status


【Discovery Mode】: Master 가 주변 Bluetooth 기기들을 탐색, MAC address를 알아내지 못한 상태, 검색 패킷을 주고 받는 상태


【Page Mode】: 상대방 Mac 주소를 알 경우 1.28초~2.56초 간격으로 Page 패킷 보냄, 아닐 경우 Inquiry 메시지 보냄


【Stand-By Mode】: 1.28 초 동안 메시지를 대기


【Connection Mode】: 서로 연결되어 있는 상태, 4가지 상태값 (Active Mode, Sniff Mode, Hold Mode, Park Mode) 을 가짐

           ┃

           ┣[Active Mode(활성모드)] : 데이터 전송이 이루어지고 있는 상태

           ┣[Sniff Mode(점검/탐지 모드)] : Slave 에서만 적용, 데이터 전송은 없고 수신되는 데이터를 점검하는 상태

           ┣[Hold Mode(중지모드)] : 원할 경우만 설정, 데이터 전송은 없으며, Sniff Mode 보다 낮은 모드지만 Park 보다는 높은 모드

           ┗[Park Mode(파크/임시 정지 모드)] : Hold Mode 보다 낮은 모드, Mac 주소를 가지지 않고, 제어 메세지만 수신하는 상태



5. Bluetooth 네트워크 연결 및 데이터 송/수신


※ Bluetooth 연결 설정


            【블루투스 기기 검색】

                         ↓

      【검색 패킷의 수신 여부 확인】

                         ↓

                 【응답 패킷】

                         ↓

                  【페이징】

                         ↓

               【연결 페어링】

                         ↓

             【데이터 송/수신】


- Bluetooth 연결의 대부분은 Master 에서 담당


- Master M, Slave S 시나리오


           【M 에서 검색(Discovery) 패킷을 send】

                                      ↓

         【S 에서 M 에서 보낸 패킷 수신 여부 확인】

                                      ↓

         【검색 패킷에 대해 M 에게 응답 패킷 send】

                                      ↓

        【M 은 연결을 준비하며 S 에게 페이징 send】

                                      ↓

     【S 는 M 의 페이징을 확인, 확인 응답 패킷 send】

                                      ↓

         【M 과 S 는 페어링 상태, 데이터를 송/수신】



6. Bluetooth 특징 및 활용


※ Android Bluetooth 의 기본 특징

- Bluetooth 표준기술은 다자간 접속을 지원.  단 Android의 경우 하나의 Bluetooth 데이터 통신만을 지원(한 종류만!)

- Android 2.0 SDK 이상에서만 지원


※ Bluetooth 관련 하드웨어나 클래스를 사용하기 위한 권한 추가 (Manifest.xml)

- android.permission.BLUETOOTH : Bluetooth 기기 간의 연결 요청/승인, 데이터 전송 등의 Bluetooth 통신을 하기 위한 권한

- android.permission.BLUETOOTH_ADMIN : Bluetooth 기기 검색, 설정 작업을 진행하기 위한 권한


※ Android BluetoothAdapter 활용

- Bluetooth 를 다루기 위한 대부분의 기능을 개발자에게 제공

- 단말기의 Bluetooth 지원 여부 확인 및 활성화 관련 기능 제공

- Bluetooth 기기의 MAC 주소를 사용해 BluetoothDevice 객체 생성

- 데이터 통신에 필요한 BluetoothServerSocket 객체를 생성

* BluetoothAdapter는 4.2.1 Jellybean(API 17, JEALLY_BEAN_MR1)까지는 BluetoothAdapter.getDefaultAdapter() API를 통해 가져올 수 있었으나 4.2.2 Jellybean(API 17, JELLY_BEAN_MR2)부터는 getSystemService(Context.BLUETOOTH_SERVICE)를 통해 얻은 BluetoothManager의 getAdapter() API를 통해 BluetoothAdapter를 가져올 수 있다.



※ BluetoothAdapter 클래스의 메소드

- static synclronized BluetoothAdapter getDefaultAdapter()

 : 단말기의 BluetoothAdapter 인스턴스 반환, 단 한개의 Bluetooth Adapter 만 지원


- String getName()

 : 단말기의 Bluetooth Adapter 이름을 return


- boolean setName(String localBluetoothName)

 : 단말기의 Bluetooth Adapter 이름을 설정, 다른 Bluetooth 기기에서는 주어진 이름으로 검색 가능, 248 문자 지정, 검색시 20~40 검색


- String getAddress()

 : 단말기의 MAC 주소 반환(manifest.xml에서 BLUETOOTH permission 필요)


- BluetoothDevice getRemoteDevice(String macAddress)

 : 인자로 주어진 macAddress 주소를 갖는 BluetoothDevice 객체를 반환, macAddress 는 반드시 대문자, 연결되어 있지 않아도 동작


- Set<BluetoothDevice> getBondedDevice()

 : 현재 단말기와 연결된 다른 단말기 또는 Bluetooth 기기의 BluetoothDevice 객체들을 반환


- static boolean checkBluetoothAddress(String macAddress)

 : 단말기의 MAC 주소가 macAddress 와 일치하는지 체크


- boolean startDiscovery()

 : 주변 Bluetooth 기기의 검색을 시작


- boolean cancelDiscovery()

 : Bluetooth 검색을 진행중이라면 검색을 종료(BLUETOOTH_ADMIN 퍼미션 필요)


- boolean isEnabled()

 : 현재 기기가 활성화 되어 있는지 체크


- getBluetoothState()

 : BluetoothAdapter.STATE_ON 과 같은 역할


- static boolean disable()

 : Bluetooth 기기를 비활성, 사용자에 의한 종료가 아닌 시스템에 의해 종료되는 방식, STATE_ON/STATEOFF


- int getState()

 : 현재 Bluetooth 의 상태값 리턴 ( STATE_ON, STATE_OFF, STATE_TURNING_OFF ), 주변 Bluetooth 기기의 ON/OFF 상태


- int getScanMode()

 : BluetoothAdapter 객체에서 실행하는 Scan Mode 를 리턴 

   ( SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE)


7. BluetoothDevice 의 역할


※ BluetoothDevice 로 기기의 장치정보를 알아낼 수 있는 자세한 메소드 및 상태 값을 알아낼 수 있다.

- 연결하고자 하는 다른 블루투스 기기의 이름, 주소, 연결 상태 등의 정보를 조회할 수 있는 클래스

- 현재 기기가 아닌 다른 블루투스 기기와의 연결 및 정보를 알아낼 때 사용


※ BluetoothDevice 클래스 메소드

- BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid)

 : 다른 기기의 SDP 에서 UUID 서비스를 제공하는지를 찾는 역할


- listenUsingRfcommWithServiceRecord(String, UUID)

 : Bluetooth 서버소켓을 이 메서드를 이용하여 다른 기기에서 생성하고 연결준비가 되어 있는지 확인


- String getAddress()

 : MAC address return


- BluetoothClass getBluetoothClass()

 : 다른 기기의 BluetoothClass 객체를 생성


- int getBondService()

 : 다른 Bluetooth 기기와 연결되어 있는지 알아냄

     - BOND_NONE : 연결되어 있지 않은 상태

     - BOND_BONDING : 연결 시도 중인 상태

     - BOND_BONDED : 연결된 상태


- String getName()

 : 다른 기기의 Bluetooth 이름을 리턴



8. BluetoothSocket 활용


※ 특징

- TCP 소켓 통신과 유사

- Slave(클라이언트 역할)는 BluetoothSocket 객체를 사용하여 연결작업을 수행

- 두 Bluetooth 를 연결하기 위해서는 한쪽은 소켓을 오픈 해야함

- Master(서버 역할) BluetoothServcerSocket 객체로 설정

- BluetoothSocket 은 실제 데이터 연결에 필요한 클라이언트 소켓을 연결하고 해제하는 기능을 담당


※ BluetoothSocket 의 주요 메서드

- void connect()

 : 다른 Bluetooth 기기와 연결을 시도하며 성공 또는 실패할 때까지 블럭


- void close()

 : Bluetooth 소켓을 닫고 모든 자원을 해제


- InputStream getInputStream()

 : Bluetooth 소켓으로부터 입력 스트림 객체를 획득, 연결이 되지 않아도 입력 스트림 객체는 획득하지만 읽을 때 IOException 발생


- OutputStream getOutputStream()

 : 출력 스트림을 획득, 연결이 되지 않아도 출력 스트림객체는 획득하지만 읽을 때 IOException 발생


- BluetoothDevice getRemoteDevice()

 : 연결 또는 연결중인 Bluetooth 기기의 BluetoothDevice 객체를 리턴



9. BluetoothServerSocket 활용


※ 특징

- TCP 연결과 비슷한 구조


- Bluetooth 데이터 통신에서 서버소켓의 역할을 담당

* 클라이언트와 소켓통신은 단 하나의 클라이언트만 통신이 가능하다.


- BluetoothSocket accept(int timeout), BluetoothSocket accept()

 : 외부 블루투스 기기에서 연결 요청을 대기하는 역할 수행


- 블루투스 연결을 하려면 반드시 BluetoothServerSocket 객체를 구현, 허락이 이루어지면 데이터 통신을 위해 Bluetooth 객체를 리턴


- void close()

 : 연결이 이루어지면 close() 를 호출, 스레드에서 안전


- accept () 는 블럭되므로 스레드로 구현


- BluetoothServerSocket 은 한번만 사용되므로 Service 컴포넌트로 구현하지 않아도 되는 이점이 존재



10. BluetoothClass 활용


※ 특징

- 다른 블루투스 기기가 수행하는 작업에 대한 정보를 얻을 때 사용

- AUDIO, CAR, TELEPHONY, HEADSET, 의료기기, PC 등

- 서비스의 대분류, 중분류 종류 파악 가능

- BluetoothClass.Device : 블루투스 기능의 종류

- BluetoothClass.Device.Major : 대부분 상수

- BluetoothClass 클래스는 블루투스 서비스가 어떤 작업을 수행하는지에 대한 큰 카테고리를 얻는데 사용

- 오디오/전화/폰/헤드셋 과 같은 기능을 수행할 수 있는지의 여부 파악 가능

- SDP (Service Discovery Protocol)요청을 통해 획득할 수 있는 실제 작업을 위한 서비스는 아님


※ BluetoothClass 의 주요 메소드

- int getDeviceClass()

- BluetoothClass.Device : 내부 클래스에서 제공하는 상수값을 리턴

        - AUDIO_VIDEO_CAMCORDER : 블루투스 기기가 캠코더 일 때

- COMPUTER_DESKTOP : PC 일때

- HEALTH_BLOOD_PRESSURE : 의료 기기일 때


- int getMajorDeviceClass()

 : 서비스 대분류 상수값을 반환


- boolean hasService(int service)

 : BluetoothClass 가 지원가능한 BluetoothClass.Service 클래스에 상수로 선언된 서비스 지원 여부 확인



11. Android Bluetooth 관련 Intent


※ 내부 Intent 를 활용하는 방법 알면 블루투스 상태를 유연하고 편리하게 관리할 수 있다.


                 【Activity】【Broadcast Receiver】【Service】


A. BluetoothAdapter의 Activity Action

 - ACTION_REQUEST_ENABLE

 - 블루투스 활성화/비활성화를 위한 퍼미션을 요구하는 대화창

 - 비추천 방식, 인텐트를 호출하여 실행하는 방법 권장

 - startActivityForResult(Intent, REQUEST_VALUE)를 호출하여 대화창의 값을 리턴

 - 액션이 실행되면 ACTION_ON_STATE_CHANGED BR Action 을 실행하여 현재 블루투스의 상태를 방송


- ACTION_REQUESET_DISCOVERABLE

- 블루투스 검색 응답 모드로 만들 때 호출하는 Activity 액션

- 디폴트로 120 동안 검색 응답모드로 동작

- 현재 기기의 블루투스는 검색 모드와 페이지 모드로 나뉘어져 다른 블루투스 기기가 보낸 패킷들에 대해 반응

- 지정된 시간 안에 검색작업을 완료 할 수 없다면 BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION 설정후 호출

- 검색모드에 있는 동안 검색작업을 동시에 실행하는 것은 좋지 않음. getScanMode() 를 사용하여 조건 지정후 실행

- SCAN_MODE_CONNECTABLE_DISCOVERABLE : 검색과 연결이 가능한 스캔 모드

- SCAN_MODE_CONNECTABLE : 검색응답모드 활성화, 로컬에서는 비활성, 페이지 모드 활성화

- SCAN_MODE_NONE : 검색응답모드 비활성화


B. BluetoothAdapter의 BR Action : Broadcast 할 수 있는 인텐트 제공

- ACTION_STATE_CHANGED

- 안드로이드 블루투스 기기의 상태(활성화/비활성화)가 변경될 때 호출되는 Action

- 수신받는 인텐트 내에 EXTRA_PREVIOUS_STATE 와 EXTRA_STATE 의 엑스트라 값으로 이전 상태와 현재 상태의

   변화된 값을 얻을 수 있음

- 블루투스 기기의 상태를 변화 시킬 수 있으며 이때 인텐트를 구현하면 변화한 상태 값을 얻을수 있음

- STATE_TURNING_ON : 다른 블루투스 기기가 ON 상태

- STATE_TURNING_OFF : OFF 상태

- STATE_ON : 로컬 블루투스 기기가 활성화 된 상태

- STATE_OFF : 비활성화 상태


- ACTION_SCAN_MODE_CHANGED

- 현재 안드로이드 블루투스 기기의 스캔 모드가 변경될 때마다 호출되는 액션


- ACTION_CONNECTION_STATE_CHANGED

- 원격 블루투스 기기의 연결상태가 변경되면 호출


- ACTION_DISCOVERY_STARTED

- 로컬 블루투스 기기가 검색 작업의 시작을 알리는 BR Action


- ACTION_DISCOVERY_FINISHED

- 로컬 블루투스 기기의 검색 작업이 종료됨을 알리는 BR Action


C. BluetoothDevice 의 BR Action

- ACTION_ACL_CONNECTED : 저수준(ACL) 에서 연결되었음을 의미


- ACTION_ACL_DISCONNECTED : 저수준(ACL) 에서 연결되어 있지 않음을 의미


- ACTION_ACL_DISCONNECTED_REQUESTED : 연결이 되지 않은 기기가 곧 연결될 것을 의미


- ACTION_BOND_STATE_CHANGED : 원격 기기의 결합상태가 변경됨을 의미


- ACTION_CLASS_CHANGED : 원격 기기의 BluetoothClass 객체의 정보가 변경되었음을 의미


- ACTION_NAME_CHANGED : 원격 장치의 이름(friendly name) 이 변경되었을 때 호출


- ACTION_FOUND : 검색과정에서의 원격 기기들이 정보를 BR 에 실어 애플리케이션에 던져 주는 역할을 하는 중요한 BR ACTION

- EXTRA_NAME : 원격 블루투스 기기의 이름

- EXTRA_DEVICE : BluetoothDevice 객체

- EXTRA_CLASS : BluetoothClass 객체



'Programming > Android Java' 카테고리의 다른 글

앱 완전종료[테스트 필수]  (0) 2014.09.18
Bluetooth@android.com  (0) 2014.09.14
Android Bluetooth 구조  (0) 2014.09.08
bluetooth overview for android QC  (0) 2014.09.08
센서를 얻어오기, 리스너 연결하기  (0) 2014.09.02