[안드로이드] USB Attached event 수신받기

|

USB Host가 지원되는 기기의 경우 USB 디바이스 연결/해제시 안드로이드에서 이벤트를 수신할 수 있다.


처음에 가장 헤맸던게,

연결 해제시 DETACHED 브로드캐스트는 정상적으로 날아오는데

ATTACHED는 뭔 짓을 해도 안날아오는것.


구글을 뒤져봐도 다들 비슷한 이야기만 하고있고....



일단 가장 먼저 확인해야 할 것은,

android.hardware.usb.action.USB_DEVICE_DETACHED 는 브로드캐스트로 날아오는게 맞는데,

android.hardware.usb.action.USB_DEVICE_ATTACHED 는 브로드캐스트가 아니다!



즉 manifest에 receiver 노드로 쓰는것이 아니라,

activity노드에 intent-filter로 걸어줘야 하는것.


비슷한 예로, 런처 액티비티나 갤러리 액티비티, 파일 브라우징어플이 있을수 있겠다.

갤러리 액티비티가 하나만 설치되어 있는 경우에는 사진파일을 보려 할 때 그 어플이 뜨지만,

뷰어 종류의 어플이 두개 이상 설치가 되어 있다면 (정확히는 지정된 intent-filter가 있는 액티비티)

"이 동작을 수행할때 사용할 어플리케이션 선택" 이라는 팝업창이 떠서

어떤 어플(액티비티)로 실행을 할지 선택할 수 있는것과 마찬가지.



정리하자면, manifest에 특정 activity에 usb attached 액션을 받겠다고 정의하고 해당 어플이 설치된 후,

usb 디바이스 연결시 자동적으로 그 액티비티가 뜨게 된다는 것.



그럼 사용법을 정리.




USB Host기능은 모든 단말에 들어가는것이 아니므로 uses-feature 노드로 해당 기능이 필요하다는것을 명시해주고,

USB Host API 역시 API Level 12부터 사용이 가능하므로 min sdk 설정.


인텐트를 수신받을 액티비티에 intent-filter를 걸어주고,

meta-data를 설정해줘야 한다.


meta-data는 어떤 디바이스에 대해 이벤트를 수신받을지 정의해놓은 파일이다.

캡춰의 아래 xml을 보면 usb-device 노드가 있는데, 여기에 필터링할 조건을 걸어주면 된다.

(빈 노드를 하나 넣어 모든 장치에 대해 수신받는것도 가능)


vendor-id, product-id, class, subclass, protocol이 있는데

이 속성 모두가 들어가지 않아도 된다.


이 값들은 안드로이드 내에서 UsbDevice라는 클래스에 정의되는값과 같은데,

각 값들은 아래의 의미를 갖고 있다.


vendor-id, product-id : 말 그대로 제조사와 제품 종류. 유의할점은 제품 종류가 모델명을 의미하지 않는다는것.

핸드폰이 디바이스모드로 연결되더라도, 카메라로 연결될 수 있고, 이동식저장소로 연결될 수 있고, 그럴때마다 product-id는 다르다는 뜻.

삼성 갤럭시S3를 CDC-NCM모드로 연결하니 S2 Debug mode 였나? 이 값으로 뜨더라.

class, subclass : 연결된 장치가 어떤 용도의 장치인지 구분하는 기준값.

요즘 OS에서 어떤 USB Memory를 연결하든 Mass Storage 라는 종류로 인식하는것은 이 값을 기준으로 인식하는것.

protocol : 장치 프로토콜 필드. API를 보면 여러개의 값을 가질 수 있는듯 한데, 갤럭시S3로 테스트해보니 0으로 반환된다.


VendorID와 Protocol ID는 안드로이드가 리눅스기반이다보니 http://www.linux-usb.org/usb.ids 에서 코드값을 확인할 수 있다.

Class, Subclass는 USB Spec에서 확인 가능. http://www.usb.org/developers/defined_class/


어쨌든 ATTACHED 액션은 브로드캐스트가 아니라는것을 명심.



출처(안드로이드 개발자 사이트)에 가보면 통신하는 샘플코드도 볼 수 있다.



출처 : http://developer.android.com/guide/topics/connectivity/usb/host.html

And