AndroidWearで取得した加速度をスマホに送信して、リアルタイムにグラフ描画するアプリを作って見ます。
この(前編)では、AndroidWear側の処理のみ紹介します。
(後編)では、mobile側のプログラムを紹介します。
グラフ描画はMPAndroidChartという便利なライブラリがあるので、こちらを利用します。
githubのライブラリを使うので、開発環境はAndroidStudioになります。
実際に作成したアプリです。
手順
wear側(前編)
1.加速度データ取得
2.加速度データ送信
mobile側(後編)
3.加速度データ受信
4.加速度をグラフにプロット
大雑把ですが、こんな流れです。
1.加速度データ取得
まずはwearで加速度を取得します。
1-1.センサーマネージャの取得
//センサーマネージャーを取得 manager = (SensorManager)getSystemService(SENSOR_SERVICE); //センサマネージャに TYPE_ACCELEROMETER(加速度センサ) を指定します。 sensor_h = manager_h.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
1-2 .SensorEventListenerインタフェースの実装
public class MainActivity extends Activity implements SensorEventListener{}
onSensorChanged
加速度センサの値に変化があると、ここの部分が実行されます。
なので、この部分に加速度データを送信するプログラムを書きます。
onAccuracyChanged
センサの精度に変更があったときに実行されます。
1-3.値の取得(onSensorChanged)
加速度を取得した時にデータ送信したいので、onSensorChanged内に送信処理を書きます。
@Override public void onSensorChanged(SensorEvent event) { if(count>= 10) { count = 0; if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { //x = (x * GAIN + event.values[0] * (1 - GAIN)); //y = (y * GAIN + event.values[1] * (1 - GAIN)); //z = (z * GAIN + event.values[2] * (1 - GAIN)); x = event.values[0]; y = event.values[1]; z = event.values[2]; mTextView.setText(String.format("X : %f\nY : %f\nZ : %f" , x, y, z)); } }else count++; }
引数のevent.values[]に加速度が格納されています。
加速度はXYZの3方向で出力されるので、それぞれevent.values[0], event.values[1], event.values[2]から取り出します。
ちなみに、心拍数のような要素が一つのデータの場合はevent.values[0]のみ用います。
3行目に注目してください。
if(count>= 10)
加速度を取得しても10回に一度だけ送信するようにしています。
これは加速度を全て送信するとmobileとwearの通信帯域が圧迫されて処理が追いつかなくなるからです。
この処理は簡単ですが、他にも数回分の加速度をまとめて送信する方法や、一定間隔で送信する方法もあります。
デバイスのセンサーによって検出頻度が変わってくるので、様子を見て変更してください。
冒頭の動画で使っているスマートウォッチはHUAWEI WATCH初代です。
2.加速度データ送信
//転送セット String SEND_DATA = x + "," + y + "," + z; if (mNode != null) { Wearable.MessageApi.sendMessage(mGoogleApiClient, mNode, SEND_DATA, null).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() { @Override public void onResult(MessageApi.SendMessageResult result) { if (!result.getStatus().isSuccess()) { Log.d(TAG, "ERROR : failed to send Message" + result.getStatus()); } } }); }
wearで加速度を取得したので、それを整形してmobileに送信します。
wearとmobileのデータ通信にはDataLayerAPIを使います。
DataLayerAPIが持つクラスにはData Item,Messageがあります。
Data Itemは同期通信、Messageは非同期通信です。
画像などの大きなデータを送るときは、Data ItemにAssetを付加します。
MainActvity.java(wear)
package yokohama.mio.sensorplot; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.support.wearable.view.WatchViewStub; import android.util.Log; import android.view.WindowManager; import android.widget.TextView; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.wearable.MessageApi; import com.google.android.gms.wearable.NodeApi; import com.google.android.gms.wearable.Wearable; import java.util.Date; public class MainActivity extends Activity implements SensorEventListener { private final String TAG = MainActivity.class.getName(); private TextView mTextView; private SensorManager mSensorManager; private GoogleApiClient mGoogleApiClient; private String mNode; private float x,y,z; int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { mTextView = (TextView) stub.findViewById(R.id.text); mTextView.setTextSize(36.0f); } }); mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { Log.d(TAG, "onConnected"); Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() { @Override public void onResult(NodeApi.GetConnectedNodesResult nodes) { if (nodes.getNodes().size() > 0) { mNode = nodes.getNodes().get(0).getId(); } } }); } @Override public void onConnectionSuspended(int i) { Log.d(TAG, "onConnectionSuspended"); } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "onConnectionFailed : " + connectionResult.toString()); } }) .build(); } @Override protected void onResume() { super.onResume(); Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL); mGoogleApiClient.connect(); } @Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); mGoogleApiClient.disconnect(); } @Override public void onSensorChanged(SensorEvent event) { if(count>= 10) { count = 0; if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { x = event.values[0]; y = event.values[1]; z = event.values[2]; mTextView.setText(String.format("X : %f\nY : %f\nZ : %f" , x, y, z)); String SEND_DATA = x + "," + y + "," + z; if (mNode != null) { Wearable.MessageApi.sendMessage(mGoogleApiClient, mNode, SEND_DATA, null).setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() { @Override public void onResult(MessageApi.SendMessageResult result) { if (!result.getStatus().isSuccess()) { Log.d(TAG, "ERROR : failed to send Message" + result.getStatus()); } } }); } } }else count++; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
次回
次回は後編です。
mobileに送信した加速度データを受信して、グラフにプロットします。
参考
Android WearのData Layer APIを試してみた|bati11 の 日記
コールバック関数 (callback function)|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
後編はいつになりますか?
記事をご覧いただきありがとうございます。
後編を掲載しました。
更新が遅くなり申し訳ございません。
またわからない点などありましたら、ご連絡ください。
AndroidWearの加速度センサ値をスマホでリアルタイムにグラフ描画する!(後編)|mio.yokohama
http://mio.yokohama/?p=461