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