Androidで、USBデバイスと通信するための準備

## 背景
* 2014年6月から、Android勉強を始めて、まだ初心者だ。
* USB CameraをAndroid external deviceとして使いたい（大きい目標だった）

## 目的
* USBデバイスと通信できるように
* 通信前に、デバイス発見、列挙、許可取得などの作業を説明する

## 子供、母、お菓子
#### 何これ？
* 私は、初めて[この文書](http://developer.android.com/guide/topics/connectivity/usb/host.html)を読んだときに、通信以外の処理は、何のつもりかのことが、全然分からない
* その他の初心者は、同感があるかもしれない
* ここで、子供、母、お菓子の例で、説明したいと思う
 * 子供 = ユーザ
 * 母  = アプリケーション
 * お菓子 = USBデバイス

#### 子供は、どうお菓子をもらえるか
* 世界に、いろいろなお菓子があるけど、母は、自分の子供を食べれるお菓子に対して、お`菓子リスト`を持っている
* このお菓子リストより、母は、現在に貰えるお菓子から、`お菓子を列挙する`、子供に選択させる
* 子供は、好きなお菓子に、`食べたい`を喋って、母は、このお菓子を子供にあげる

## 通信前に、いろいろな作業を説明する
####  `菓子リスト`
* 母は、持っている`菓子リスト`が、res/xmlの下に、放置できる（例：res/xml/device_filter.xml）
* 希望する USB デバイスを特定した対応するリソースファイルを宣言する方法の例を以下に

```
<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" />
</resources>
```

* 以上の条件より、アプリケーション（母）が、デバイスを選べれて、その以外のお菓子を無視する

* 導入

```

<activity ...>
...
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>

    <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/device_filter" />
</activity>
```

* 以下のログを参照して、vendor-idなどの意味を理解できると思う

```
UsbDevice[mName=/dev/bus/usb/001/002,mVendorId=1133,mProductId=2093,mClass=239,mSubclass=2,mProtocol=1,mInterfaces=[Landroid.os.Parcelable;@41eabd00]
```

#### `お菓子を列挙する`
* アプリケーション(母)は、`菓子リスト`より、選べ出したお菓子を、ユーザ（子供）に列挙する

```
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
...
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
    UsbDevice device = deviceIterator.next()
    //your code
}
```

* Dialogframentなどクラスを使って、ユーザ（子供）を見せるようになる


#### `食べたい`
* USB デバイスと通信する前に、アプリケーションはユーザから許可を得る必要がある。同じく、子供は、「食べたい」と言って、母は分かるようになる

* 実装に対して、三つのポイントがある

* 1. ブロードキャストレシーバを作成

```
private static final String ACTION_USB_PERMISSION =
    "com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if(device != null){
                      //call method to set up device communication
                   }
                } 
                else {
                    Log.d(TAG, "permission denied for device " + device);
                }
            }
        }
    }
};
```

* 2. registerReceiverを、onCreateメソッドに設定する

```
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
private static final String ACTION_USB_PERMISSION =
    "com.android.example.USB_PERMISSION";
...
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
```

* 3. ユーザにデバイスと接続するための許可を得るためのダイアログを表示するには、以下のように requestPermission() メソッドを呼び出す

```
UsbDevice device;
...
mUsbManager.requestPermission(device, mPermissionIntent);
```


## 補足
* この文書は、初心者は、USBデバイスを通信するために、デバイス発見、列挙、許可取得を説明するけど、詳しい内容を[ここ](http://developer.android.com/guide/topics/connectivity/usb/host.html)の文書を見てください