前回は、
Developer Toolsをダウンロードする
NeroSky社からAndroid用のDeveloper Toolsが無料で提供されていますので、
[Add to Cart]
注)
ダウンロードが完了したら、
| ThinkGear. | Developer Tool本体 | 
|---|---|
| api_ | ThinkGear. | 
| android_ | 利用ガイド | 
| src | Developer Toolsのサンプルソース | 
Android Projectの構築を行う
前回、
主なファイルとディレクトリは次のとおりです。
| AndroidManifest. | アプリケーションを構築する際に必要な情報を定義しています | 
|---|---|
| srcディレクトリ | Javaのプログラムが格納するディレクトリです | 
| resディレクトリ | 画像ファイルや画面のレイアウト定義などのリソースファイルを管理するディレクトリです | 
| libsディレクトリ | 外部のjarファイルを格納するディレクトリです。 | 
Projectをインポートする
解凍したAndroidのプロジェクトファイルを、
Androidのフォルダから、
Existing Android Code Into Workspaceダイアログが表示されるので、
プロジェクトエクスプローラーの画面に
ThinkGear.jarをインポートする 
Neurosky社からダウンロードした、
AndroidManifest.xmlを確認してみる 
AndroidでBluetoothを利用する場合、
<uses-permission android:name="android.permission.BLUETOOTH" />
Bluetoothを利用するため、
レイアウトを構築する
レイアウトの構築をするには色々な手順がありますが、
レイアウトに利用している画像ファイルは、
プログラムの中身を見てみる
[src]
それぞれのプログラムは、
- ThinkGear.
java:ThinkGear. javaは、 脳波デバイスとBluetoothを接続したり、 ThinkGearのDeveloper Toolsを利用して脳波データを取得する機能です。  - MainActivity.
java:MainActivity. javaは、 主に脳波デバイスの接続状況や脳波データを受け取ってグラフをダイナミックに表示する機能です。  
実際のソースコードを確認しながら、
脳波デバイスとBluetoothの接続を行う
Bluetooth接続してイベントハンドラを登録します。
private void createTGDevice(){
    // B3Bandとのbluetooth接続
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(bluetoothAdapter == null) {
        // Alert user that Bluetooth is not available
        Log.w("EEGReader", "Bluetooth not available");
    }else {
        /* create the TGDevice */
        tgDevice = new TGDevice(bluetoothAdapter, handler);
        if(tgDevice == null){
            Log.w("EEGReader", "BrainBand not available");
        }
    }
}
BluetoothAdapter.
脳波デバイスからデータを受け取る
Handlerクラスでは、
受け取ったメッセージを処理します。
private final Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case TGDevice.MSG_STATE_CHANGE:
                switch (msg.arg1) {
                case TGDevice.STATE_IDLE:
                break;
            case TGDevice.STATE_CONNECTING:
                Log.d("EEGReader", "ThinkGear Connecting...");
                tgData.status("connecting");
                if(myView != null) {
                     myView.b3status(tgData.status());
                }    
                break;
            case TGDevice.STATE_CONNECTED:
                Log.d("EEGReader", "ThinkGear Connected");
                tgData.status("connected");
                if(myView != null) {
                     myView.b3status(tgData.status());
                }
                tgDevice.start();
                break;
            case TGDevice.STATE_NOT_FOUND:
                Log.w("EEGReader", "ThinkGear Can't find");
                break;
            case TGDevice.STATE_NOT_PAIRED:
                Log.w("EEGReader", "ThinkGear not paired");
                break;
            case TGDevice.STATE_DISCONNECTED:
                Log.d("EEGReader", "ThinkGear Disconnected");
                tgData.status("disconnected");
                if(myView != null) {
                                     myView.b3status(tgData.status());
                }
                break;
        case TGDevice.MSG_POOR_SIGNAL:
            tgData.poor_signal(msg.arg1);
            if(myView != null) myView.sigQ(tgData.poor_signal());
            break;
        case TGDevice.MSG_HEART_RATE:
            break;
        case TGDevice.MSG_ATTENTION:
            tgData.attention(msg.arg1);
            if(myView != null){
                    myView.attention(tgData.attention());
            }
            break;
        case TGDevice.MSG_MEDITATION:
            tgData.meditation(msg.arg1);
            if(myView != null){
                 myView.meditation(tgData.meditation());
            }
            break;
        case TGDevice.MSG_BLINK:
            tgData.blink(msg.arg1);
            if(myView != null){
                    myView.blink(tgData.blink());
            }
            break;
        case TGDevice.MSG_LOW_BATTERY:
            Log.w("EEGReader", "ThinkGear Low battery!");
            break;
        case TGDevice.MSG_EEG_POWER:
            tgEegPower = (TGEegPower)msg.obj;
            tgData.eeg(tgEegPower);
            if(myView != null) {
                myView.eeg(tgData.eeg());
            }
            break;
        default:
            break;
        }
    }
};
取得できるメッセージの概要は、
| TGDevice. | デバイスとの接続の状態 | 
|---|---|
| TGDevice. | デバイスとの通信状態 | 
| TGDevice. | 心拍数 | 
| TGDevice. | 集中度 | 
| TGDevice. | リラックス度 | 
| TGDevice. | 瞬き | 
| TGDevice. | 脳波デバイスのバッテリーが少ない状態 | 
| TGDevice. | 脳波データのより詳細なデータ | 
TGDevice.
脳波デバイスとの接続状態を取得する
TGDevice.
| TGDevice. | 脳波デバイスと接続した | 
|---|---|
| TGDevice. | 脳波デバイスと接続が完了した | 
| TGDevice. | 脳波デバイスの信号を取得できない | 
| TGDevice. | 脳波デバイスとのペアリングに失敗 | 
| TGDevice. | 脳波デバイスとの通信が切断 | 
より詳細な脳波データを取得する
TGDevice.
| delta | 深い眠りの状態 | 
|---|---|
| theta | リラックスしている状態 | 
| lowAlpha | とても集中している状態 | 
| highAlpha | lowAlphaほどではないが、 | 
| lowBeta | 日常生活 | 
| highBeta | やや緊張している状態 | 
| lowGamma | やや興奮状態 | 
| highGamma | イライラしている状態 | 
これら詳細データは、
では次に、
Viewを構築する
脳波デバイスからデータを取得することができるようになったので、
脳波デバイスとの接続状況を表示します。
public void b3status(String st){
    if (st.equals("connected")){
        b3status.connected();
    }else if(st.equals("disconnected")){
        b3status.disconnected();
    }else if(st.equals("connecting")){
        b3status.connecting();
    }else{
        b3status.set(st);
    }
}
脳波デバイスとの接続状況は、
public void meditation(int to){
    if(to 
Scaleアニメーションを利用して画像を拡大縮小します。
private class Ball{
    ImageView img = null;
    float now = 1.0f;
    public Ball(int rid){
        img = (ImageView)findViewById(rid);
        img.setAlpha(100);
    }
    public void scale(float to){
        ScaleAnimation scale = new ScaleAnimation(
                now, to, // x
                now, to, // y
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        scale.setDuration(1000);
        scale.setFillAfter(true);
        
        img.setAlpha(255);
        img.startAnimation(scale);
        now = to;
    }
}
波などの詳細データをグラフアニメーションで描画します。
public void eeg(int[] val){
    for (int i = 0; i  20.0) ? 20.0f : eegVal;
}
Scaleアニメーションを利用して画像を拡大縮小します。
private class Bar{
    ImageView img = null;
    float now = 1.0f;
    public Bar(int rid){
        img = (ImageView)findViewById(rid);
        img.setAlpha(100);
    }
    public void scale(float to){
        ScaleAnimation scale = new ScaleAnimation(
                now,  to,
                1.0f, 1.0f
        );
        scale.setDuration(1000);
        scale.setFillAfter(true);
        
        img.setAlpha(255);
        img.startAnimation(scale);
        now = to;
    }
}
円グラフや棒グラフをアニメーション的に表示する部分に関しては、
デバックする際の注意点
AVD
全3回にわたり、