관리 메뉴

드럼치는 프로그래머

[안드로이드] [번역] 안드로이드 멋진 아이디어 - 안드로이드 오픈 악세서리 본문

★─Programing/☆─Android

[안드로이드] [번역] 안드로이드 멋진 아이디어 - 안드로이드 오픈 악세서리

드럼치는한동이 2013. 3. 4. 18:54

A Bright Idea: Android Open Accessories

[이 포스트는 안드로이드 개발자를 응원하는 Justin Mattson 및 안드로이드 시스템 팀에서 근무하는 Erik Gilling 에 의해 작성되었습니다. — Tim Bray]


지금까지 안드로이드 USB 포트는 개발자들이 감히 범접할 수 없는 영역이었습니다. 하지만 지난 주 (주>그러니까 2011년 5월 12일...;;;) 구글 I/O 에서 우리는 안드로이드 오픈 악세서리(Android Open Accessory API) API 를 공개하였습니다. 이 API 들을 이용하면, 안드로이드 3.1 (허니콤) 혹은 안드로이드 2.3.4 (진저브레드 최신 버전) 단말과 호환되는 악세서리를 개발할 수 있습니다. 어떤 특별한 라이센스도 필요없고 요금을 지불하지 않아도 말입니다. 이 새로운 "악세서리 모드" 를 통해, 안드로이드 디바이스는 USB 호스트 모드를 동작하지 않는 상황에서도 USB 장치와 연결될 수 있습니다. 아. 참고삼아 말씀드리면, 이번 포스트에서는 새로운 악세서리 모드에 관해서만 이야기할 예정입니다만, 향후에는 USB 호스트 모드를 지원 하는 안드로이드 디바이스에서 활용할 수 있는 API 도 공개할 예정입니다.


그런데 잠깐. 안드로이드는 원래 USB 포트를 갖고 있으니, 당연히 다른 악세서리들과 연결될 수 있는거 아닌가요? 단지 USB 포트를 갖고 있는 것 만으로 왜 악세서리들을 지원할 수 없는지 여러분의 이해를 돕기위하여, USB 가 동작하는 방식을 잠깐 설명드리는 편이 좋을것 같습니다. USB 는 비대칭적인 프로토콜입니다. 하나의 디바이스는 USB 호스트로 동작하게되며, 이에 연결된 다른 디바이스들은 모두 그저 USB 디바이스로 동작하게 됩니다. 예를 들어 PC 세상 에서는, 노트북이나 데스크탑이 USB 호스트의 역할을 수행하며, 프린터, 마우스, 웹캠등이 USB 디바이스로 동작하게 되지요. USB 호스트는 크게 두 가지 주요한 역할을 수행합니다. 첫 번째 버스 마스터(bus master) 역할 을 수행하며, 어떤 디바이스가 어떤 타이밍에 데이터를 전송할지를 제어합니다. 그리도 두 번째 역할은 바로 전원을 공급하는 것 입니다.


안드로이드가 이런 전통적인 방식으로 USB 악세서리를 지원하고자 한다면, 큰 문제에 하나 있습니다. USB 호스트 모드를 지원하고 있는 안드로이드 디바이스가 거의 없다는 점 이지요. 그리고 이에대한 안드로이드 개발 팀의 해결책은 일반적인 USB 관계를 뒤짚어 버리는 것 입니다. 새롭게 추가된 안드로이드 악세서리 모드에서 안드로이드 폰/타블렛은 USB 디바이스로 동작하며, 악세서리가 USB 호스트 모드로서 동작하게 됩니다. 따라서, 악세서리는 버스 마스터 인 동시에 파워를 제공해야 합니다.


연결 맺기

악세서리 장치가 안드로이드 디바이스와 연결되는 과정은 아주 단순합니다. 악세서리가 USB 호스트 기능을 정상적으로 제공하기만 한다면, 간단한 핸드쉐이크 과정을 구현하여, 안드로이드 상에서 동작하는 어플리케이션과 양방향으로 통신 가능한 커넥션을 수립할 수 있습니다.


악세서리가 연결 가능한 디바이스를 발견하면 핸드 쉐이크 과정이 시작됩니다. 악세서리는 안드로이드 디바이스가 제공하는 VID/PID 값을 이용하여 해당 디바이스를 식별할 수 있습니다. 이 값은 디바이스 제조사와 디바이스 모델에 따라 달라집니다. 우선, 안드로이드 디바이스로 컨트롤 처리(Control Transaction) 신호를 전송하여, 해당 디바이스가 악세서리 모드를 지원하는지 여부를 판별 합니다.


안드로이드 디바이스가 악세서리 모드를 지원하는 것으로 확인 되면, 악세서리는 컨트롤 처리 신호 형식으로 일련의 문자열을 전송합니다. 이 문자열을 이용하여, 안드로이드 디바이스는 해당 악세서리와 호환되는 어플리케이션을 찾아낼 수 있으며, 만일 현재 디바이스 상에 호환 어플리케이션이 없을 경우, 어플리케이션을 다운로드 받을 수 있는 URL 을 전달 할 수도 있습니다. 그런 다음 악세서리는 안드로이드 디바이스에게 이제 악세서리 모드로 진입하라고 메세지를 전달 합니다.


그러면 안드로이드 디바이스는 기존 버스를 끊고, 새로운 VID/PID 조합 값을 갖고 다시 버스를 연결합니다. 이 새로운 VID/PID 값은 악세서리 모드에 진입한 디바이스와 대응되는 값 입니다. 예를 들어, 구글의 VID 는 0x18D1 이고, PID 는 0x2D01 혹은 0x2D00 값을 갖습니다. 안드로이드 디바이스단에 적절한 어플리케이션이 시작되면, 악세서리는 최초 Bulk IN / Bulk OUT Endpoint 를 이용하여 디바이스와 통신 할 수 있습니다.


이 프로토콜은 구현하기 쉽습니다. 만일 여러분이 ADK (Accessory Developement Kit) 나 다른 USB Host Shield 호환 Arduino 플랫폼을 사용하신다면, AndroidAccessory 라이브러리를 이용할 수도 있습니다. ADK 는 악세서리를 구현하기 위한 가장 손 쉬운 방법 중 하나이지만, 이를 사용하지 않더라도, 안드로이드 오픈 악세서리가 요구하는 기능과 스펙만 만족한다면 어떠한 디바이스도 안드로이드 악세서리 디바이스로 동작할 수 있습니다.


악세서리와 통신하기

안드로이드 디바이스와 악세서리 사이에 저수준의 USB 연결이 이루어진 후에는, 이제 어플리케이션이 활약해야 할 시점입니다. 어떤 안드로이드 어플리케이션이던 간에 지정된 USB 악세서리와 통신할 수 있습니다. 안드로이드 메니페스트 파일에 다음과 같이 선언하시면 됩니다.


<activity android:name=".UsbAccessoryActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>

그리고 다음과 같이 이 엑티비티가 지원하는 악세서리 목록을 지정할 수 있습니다.

<resources>
<usb-accessory manufacturer="Acme, Inc" model="Whiz Banger" version="7.0" />
</resources>

악세서리가 연결되면 안드로이드 시스템은 인텐트를 전송합니다. 그러면 사용자에게 해당 인텐트에 부합하는 어플리케이션 목록이 팝업되어 나타납니다. 만일 적절한 어플리케이션이 디바이스에 설치되어 있지 않은 경우, 악세서리는 관련 어플리케이션을 다운 받을 수 있는 URL 정보를 제공 할 수도 있습니다. 사용자는 해당 URL 을 이용하여 안드로이드 마켓에 접근할 수 있겠지요.


이렇게, 어플리케이션이 시작되고 나면, 앱은 안드로이드 SDK 에 포함된 Android Open Accessory API 를 통해 악세서리 디바이스와 데이터를 주고 받을 수 있습니다. API 를 이용하면 임의의 데이터를 주고 받을 수 있도록 하나의 FileInputStream 과 FileOutputStream 을 열 수 있으며, 이 연결 채널을 이용하여 주고 받는 데이타 프로토콜은 전적으로 어플리케이션과 악세서리 제조자에게 맡겨져 있습니다.


Accessory API 를 사용한 간단한 예제를 한 번 살펴보지요.

public class UsbAccessoryActivity extends Activity {
private FileInputStream mInput;
private FileOutputStream mOutput;

private void openAccessory() {
UsbManager manager = UsbManager.getInstance(this);
UsbAccessory accessory = UsbManager.getAccessory(getIntent());

ParcelFileDescriptor fd = manager.openAccessory(accessory);

if (fd != null) {
mInput
= new FileInputStream(fd);
mOutput
= new FileOutputStream(fd);
} else {
// Oh noes, the accessory didn’t open!
}
}
}


향후 계획

앞으로 진행하고 싶은 몇 가지 아이디어가 있습니다. 한 가지 이슈는 "전력 문제" 를 해결하는 것 입니다. 간단한 만보계가 여러분의 넥서스 S 에 파워를 제공해야 한다고 생각하면 어째 좀 이상하지요? 우리는 USB 호스트 모드로 동작하되, 단지 버스 마스터의 역할만 수행하며, 파워는 제공하지 않도록 할 수 있는지 여러가지로 방안을 모색하고 있습니다. 폰 상에서 음악을 듣고, 음악을 저장하는 일은 매우 자연스러운 일이기 때문에, USB 를 통해 오디오를 전송하는 기능도 지원하고자 계획하고 있습니다. 그리고 마지막으로, 휴대폰을 위해 보다 일반적인 입력 장치들을 제공할 수 있는 방안에 대해서도 고려하고 있습니다. 보다 생산적인 일에 휴대폰을 잘 활용할 수 있도록 말이지요. 이 모든 기능들이 꽤나 흥미진진해 보이시지 않나요?


악세서리 모드는 안드로이드 세상에 새로운 가능성을 열어 줄 것 이며, 대채로운 안드로이드 친구들이 나타날 것 입니다. 우리는 사람들이 어떤 새로운 아이디어를 보여줄기 정말로 기대하고 있습니다. 악세서리와 관련된 예제와 문서들은 지금 바로 온라인에서 열람이 가능합니다. 도전하세요!

 

[출처] http://huewu.blog.me/110116387833?Redirect=Log&from=postView

 

Comments