AndroidでEddystone信号を受信してみよう

## AndroidでEddystone信号を受信してみよう

Eddystoneの公式HPのサンプルソースコードは、Android 5.0向けになっているので、 4.3,4.4のAPIで記述してみる。

### Manifestファイルに特権の追加

```xml
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
```

Android Play にアプリをアップロードする際は、Bluetooth 4.0 LE搭載の機種でしか動作できませんよというおまじないも、Manifestファイルに記述してください。

```xml
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
```

### ソースコード記述編

#### Bluetooth Adapterの取得

```java

final BluetoothManager bluetoothManager =
        (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();

```

### Bluetooth LEデバイスの検索

```java
mBluetoothAdapter.startLeScan(mLeScanCallback);
```

を呼び出すと、Bluetooth LEデバイスの探索を開始します。
コールバック関数の中身ですが、

```java
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi,byte[] scanRecord) {
         // デバイスが検出される度に呼び出されます。
    });
};
```

実は、上記のコードだけで、Eddystoneを検出することができているんです。

####取り出し例

```java
if(scanRecord.length > 14)
{
    if((scanRecord[0] == (byte) 0x02) &&
       (scanRecord[1] == (byte) 0x01) &&
       (scanRecord[2] == (byte) 0x06) &&
       (scanRecord[3] == (byte) 0x03) &&
       (scanRecord[4] == (byte) 0x03) &&
       (scanRecord[5] == (byte) 0xaa) &&
       (scanRecord[6] == (byte) 0xfe) &&
       (scanRecord[8] == (byte) 0x16) &&
       (scanRecord[9] == (byte) 0xaa) &&
       (scanRecord[10] == (byte) 0xfe))
    {
        switch(scanRecord[11])
        {
            case 0x0:
                Log.d(TAG,"Eddystone-UID");
                Log.d(TAG,"Ranging Data=" + IntToHex2(scanRecord[12]));

                String namespace =
                                    IntToHex2(scanRecord[13]) +
                                    IntToHex2(scanRecord[14]) +
                                    IntToHex2(scanRecord[15]) +
                                    IntToHex2(scanRecord[16]) +
                                    IntToHex2(scanRecord[17]) +
                                    IntToHex2(scanRecord[18]) +
                                    IntToHex2(scanRecord[19]) +
                                    IntToHex2(scanRecord[20]) +
                                    IntToHex2(scanRecord[21]) +
                                    IntToHex2(scanRecord[22]);

                String uid =
                                    IntToHex2(scanRecord[23]) +
                                    IntToHex2(scanRecord[24]) +
                                    IntToHex2(scanRecord[25]) +
                                    IntToHex2(scanRecord[26]) +
                                    IntToHex2(scanRecord[27]) +
                                    IntToHex2(scanRecord[28]);
                
                Log.d(TAG,namespace+uid);
                break;

            case 0x10:
                Log.d(TAG,"Eddystone-URL");
                Log.d(TAG,"TX Power=" + IntToHex2(scanRecord[12]));

                int len = scanRecord[7] - 6;

                String Scheme = "";

                switch(scanRecord[13])
                {
                     case 0x0:
                          Scheme = "http://www.";
                          break;

                     case 0x1:
                          Scheme = "https://www.";
                          break;

                     case 0x2:
                          Scheme = "http://";
                          break;

                     case 0x3:
                          Scheme = "https://";
                          break;
                }

                String url = "";

                for(int i = 0 ; i < len ; i++)
                {
                    url = url + decodeURL(scanRecord[14 + i]);
                }

                Log.d(TAG,Scheme + url);
                break;

           case 0x20:
                Log.d(TAG,"Eddystone-TLM");
                Log.d(TAG,"Version=" + IntToHex2(scanRecord[12]));
                Log.d(TAG,"VBATT=" + IntToHex2(scanRecord[13]) + IntToHex2(scanRecord[14]));
                Log.d(TAG,"TEMP=" + IntToHex2(scanRecord[15]) + IntToHex2(scanRecord[16]));
                Log.d(TAG,"ADVCNT=" + IntToHex2(scanRecord[17]) + IntToHex2(scanRecord[18])+ IntToHex2(scanRecord[19]) + IntToHex2(scanRecord[20]));
                Log.d(TAG,"SECCNT=" + IntToHex2(scanRecord[21]) + IntToHex2(scanRecord[22])+ IntToHex2(scanRecord[23]) + IntToHex2(scanRecord[24]));
                break;
          }
     }
}
```

URLをデコードするための関数の定義

```java
private String decodeURL(int Value)
    {
        switch(Value)
        {
            case 0:
                return ".com/";

            case 1:
                return ".org/";

            case 2:
                return ".edu/";

            case 3:
                return ".net/";

            case 4:
                return ".info/";

            case 5:
                return ".biz/";

            case 6:
                return ".gov/";

            case 7:
                return ".com";

            case 8:
                return ".org";

            case 9:
                return ".edu";

            case 10:
                return ".net";

            case 11:
                return ".info";

            case 12:
                return ".biz";

            case 13:
                return ".gov";

        }

        if((Value > 0x20) && (Value < 0x7f))
        {
            return String.format("%c",Value);
        }

        return "";
    }
```