AndroidWearの加速度センサ値をスマホでリアルタイムにグラフ描画する!(後編)

  • このエントリーをはてなブックマークに追加
  • Pocket

AndroidWearで取得した加速度をスマホに送信して、リアルタイムにグラフ描画するアプリを作ります。

(前編)ではスマートウォッチで取得した加速度をスマートフォンへ送信する処理を書きました。

この(後編)ではスマートウォッチから受け取った加速度をMPAndroidChartというライブラリを使ってリアルタイムにグラフ描画します。

手順

wear側(前編)

1.加速度データ取得

2.加速度データ送信

mobile側(後編)※今回

3.加速度データ受信

4.加速度をグラフにプロット

3.加速度データ受信

ウェアラブルからのデータを受け取るため、GoogleApiClientを使います。

  1. GoogleApiClientのインスタンスを作成し、

  2. GoogleApiClientに接続して、

  3. GoogleApiClientの結果を受け取る。

という流れです。

3.1.GoogleApiClientのインスタンスを作成

onCreate内でGoogleApiClientのインスタンスを作成します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//GoogleApiClientインスタンス生成
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed:" + connectionResult.toString());
}
})
.addApi(Wearable.API)
.build();
mChart = (LineChart) findViewById(R.id.lineChart);
mChart.setDescription(null); // 表のタイトルを空にする
mChart.setData(new LineData()); // 空のLineData型インスタンスを追加
}
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //GoogleApiClientインスタンス生成 mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "onConnectionFailed:" + connectionResult.toString()); } }) .addApi(Wearable.API) .build(); mChart = (LineChart) findViewById(R.id.lineChart); mChart.setDescription(null); // 表のタイトルを空にする mChart.setData(new LineData()); // 空のLineData型インスタンスを追加 }
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //GoogleApiClientインスタンス生成
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult connectionResult) {
                    Log.d(TAG, "onConnectionFailed:" + connectionResult.toString());
                }
            })
            .addApi(Wearable.API)
            .build();
    mChart = (LineChart) findViewById(R.id.lineChart);
    mChart.setDescription(null); // 表のタイトルを空にする
    mChart.setData(new LineData()); // 空のLineData型インスタンスを追加
}

3.2.GoogleApiClientに接続

onStart内で記述します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Override
protected void onStart() {
super.onStart();
//GoogleApiClient接続
mGoogleApiClient.connect();
}
@Override protected void onStart() { super.onStart(); //GoogleApiClient接続 mGoogleApiClient.connect(); }
@Override
protected void onStart() {
    super.onStart();
    //GoogleApiClient接続
    mGoogleApiClient.connect();
}

3.3.GoogleApiClientの結果を受け取る。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@Override
public void onConnected(Bundle bundle) {
        //GoogleApiClient 接続成功時に呼ばれます。
Log.d(TAG, "onConnected");
Wearable.MessageApi.addListener(mGoogleApiClient, this);
}
@Override
public void onConnectionSuspended(int i) {
//接続中断時に呼ばれます。
Log.d(TAG, "onConnectionSuspended");
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
//メッセージ(データ)が来たら呼ばれます。
xTextView.setText(messageEvent.getPath());
//受け取ったデータmsgはコンマ区切りのcsv形式なので、value[]にそれぞれ格納します。
String msg = messageEvent.getPath();
String[] value = msg.split(",", 0);
}
@Override public void onConnected(Bundle bundle) {         //GoogleApiClient 接続成功時に呼ばれます。 Log.d(TAG, "onConnected"); Wearable.MessageApi.addListener(mGoogleApiClient, this); } @Override public void onConnectionSuspended(int i) { //接続中断時に呼ばれます。 Log.d(TAG, "onConnectionSuspended"); } @Override public void onMessageReceived(MessageEvent messageEvent) { //メッセージ(データ)が来たら呼ばれます。 xTextView.setText(messageEvent.getPath()); //受け取ったデータmsgはコンマ区切りのcsv形式なので、value[]にそれぞれ格納します。 String msg = messageEvent.getPath(); String[] value = msg.split(",", 0); }
@Override
public void onConnected(Bundle bundle) {
        //GoogleApiClient 接続成功時に呼ばれます。
    Log.d(TAG, "onConnected");
    Wearable.MessageApi.addListener(mGoogleApiClient, this);
}

@Override
public void onConnectionSuspended(int i) {
    //接続中断時に呼ばれます。
    Log.d(TAG, "onConnectionSuspended");
}

@Override
public void onMessageReceived(MessageEvent messageEvent) {
    //メッセージ(データ)が来たら呼ばれます。
    xTextView.setText(messageEvent.getPath());
    //受け取ったデータmsgはコンマ区切りのcsv形式なので、value[]にそれぞれ格納します。
    String msg = messageEvent.getPath();
    String[] value = msg.split(",", 0);
}

ここまでで、ウェアラブルで取得し送られて来た加速度データを、スマホ側で取得できるようになりました。

4.加速度をグラフにプロット

最後に取得した加速度データをMPAndroidChartを使ってグラフにプロットしていきます。

グラフ描画にはMPAndroidChartライブラリを用います。

導入はとても簡単です。

MPAndroidChart導入

プロジェクト(ルート直下)のbuild.gradle内に下記を設定します。

ハイライトが追記部分です。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
allprojects {
repositories {
jcenter()
maven {
url "http://jitpack.io"
}
}
}
allprojects { repositories { jcenter() maven { url "http://jitpack.io" } } }
allprojects {
    repositories {
        jcenter()
        maven {
            url "http://jitpack.io"
        }
    }
}

mobileのbuild.gradle内に下記を設定します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
dependencies {
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
}
dependencies { compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' }
dependencies {
    compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
}

レイアウト

レイアウトファイルでグラフを表示します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.matu_mio.graphdraw.MainActivity">
<com.github.mikephil.charting.charts.LineChart
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lineChart"/>
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/xValue"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/yValue"
android:layout_below="@+id/xValue"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zValue"
android:layout_below="@+id/yValue"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.matu_mio.graphdraw.MainActivity"> <com.github.mikephil.charting.charts.LineChart android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/lineChart"/> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/xValue" android:layout_below="@+id/textView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/yValue" android:layout_below="@+id/xValue" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/zValue" android:layout_below="@+id/yValue" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.matu_mio.graphdraw.MainActivity">


    <com.github.mikephil.charting.charts.LineChart
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lineChart"/>


    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/xValue"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/yValue"
        android:layout_below="@+id/xValue"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/zValue"
        android:layout_below="@+id/yValue"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</android.support.constraint.ConstraintLayout>

これでスマートウォッチで取得した加速度がリアルタイムでグラフ描画できました!

最後にソースコード

wear

mobile

ActivityMain.java(wear)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.example.matu_mio.graphdraw;
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.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.view.View;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends Activity implements SensorEventListener {
private final String TAG = MainActivity.class.getName();
private final float GAIN = 0.9f;
private TextView mTextView;
private SensorManager mSensorManager;
private GoogleApiClient mGoogleApiClient;
private String mNode;
private float x,y,z;
int count = 0;
//final DateFormat df = new SimpleDateFormat("HH:mm:ssSSS");
private Date date;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mTextView = (TextView) findViewById(R.id.text);
mTextView.setTextSize(30.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");
// NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(NodeApi.GetConnectedNodesResult nodes) {
//Nodeは1個に限定
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>= 2) {
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];
if (mTextView != null)
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) {
}
}
package com.example.matu_mio.graphdraw; 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.activity.WearableActivity; import android.support.wearable.view.BoxInsetLayout; import android.support.wearable.view.WatchViewStub; import android.util.Log; import android.view.View; 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.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class MainActivity extends Activity implements SensorEventListener { private final String TAG = MainActivity.class.getName(); private final float GAIN = 0.9f; private TextView mTextView; private SensorManager mSensorManager; private GoogleApiClient mGoogleApiClient; private String mNode; private float x,y,z; int count = 0; //final DateFormat df = new SimpleDateFormat("HH:mm:ssSSS"); private Date date; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mTextView = (TextView) findViewById(R.id.text); mTextView.setTextSize(30.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"); // NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await(); Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() { @Override public void onResult(NodeApi.GetConnectedNodesResult nodes) { //Nodeは1個に限定 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>= 2) { 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]; if (mTextView != null) 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) { } }
package com.example.matu_mio.graphdraw;

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.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.view.View;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MainActivity extends Activity implements SensorEventListener {
    private final String TAG = MainActivity.class.getName();
    private final float GAIN = 0.9f;

    private TextView mTextView;
    private SensorManager mSensorManager;
    private GoogleApiClient mGoogleApiClient;
    private String mNode;
    private float x,y,z;
    int count = 0;
    //final DateFormat df = new SimpleDateFormat("HH:mm:ssSSS");
    private Date date;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        mTextView = (TextView) findViewById(R.id.text);
        mTextView.setTextSize(30.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");

//                        NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
                        Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
                            @Override
                            public void onResult(NodeApi.GetConnectedNodesResult nodes) {
                                //Nodeは1個に限定
                                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>= 2) {
            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];
                if (mTextView != null)
                    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) {

    }
}

activity_main.xml(wear)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.matu_mio.graphdraw.MainActivity"
tools:deviceIds="wear">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_world"
app:layout_box="all" />
<TextView
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:textColor="@android:color/white"
app:layout_box="all" />
</android.support.wearable.view.BoxInsetLayout>
<?xml version="1.0" encoding="utf-8"?> <android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.matu_mio.graphdraw.MainActivity" tools:deviceIds="wear"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_world" app:layout_box="all" /> <TextView android:id="@+id/clock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|start" android:textColor="@android:color/white" app:layout_box="all" /> </android.support.wearable.view.BoxInsetLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.matu_mio.graphdraw.MainActivity"
    tools:deviceIds="wear">

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_world"
        app:layout_box="all" />

    <TextView
        android:id="@+id/clock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|start"
        android:textColor="@android:color/white"
        app:layout_box="all" />

</android.support.wearable.view.BoxInsetLayout>

MainActivity.java(mobile)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.example.matu_mio.graphdraw;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
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.wearable.MessageApi;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Wearable;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, MessageApi.MessageListener{
private static final String TAG = MainActivity.class.getName();
private GoogleApiClient mGoogleApiClient;
TextView xTextView;
TextView yTextView;
TextView zTextView;
LineChart mChart;
int x,y,z;
String[] names = new String[]{"x-value", "y-value", "z-value"};
int[] colors = new int[]{Color.RED, Color.GREEN, Color.BLUE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
xTextView = (TextView)findViewById(R.id.xValue);
yTextView = (TextView)findViewById(R.id.yValue);
zTextView = (TextView)findViewById(R.id.zValue);
ActionBar ab = getActionBar();
//ab.hide();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed:" + connectionResult.toString());
}
})
.addApi(Wearable.API)
.build();
mChart = (LineChart) findViewById(R.id.lineChart);
mChart.setDescription(null); // 表のタイトルを空にする
mChart.setData(new LineData()); // 空のLineData型インスタンスを追加
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
Wearable.MessageApi.removeListener(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.my, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//if (id == R.id.action_settings) {
// return true;
//}
return super.onOptionsItemSelected(item);
}
@Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
Wearable.MessageApi.addListener(mGoogleApiClient, this);
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended");
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
xTextView.setText(messageEvent.getPath());
String msg = messageEvent.getPath();
String[] value = msg.split(",", 0);
xTextView.setText(String.valueOf(value[0]));
yTextView.setText(String.valueOf(value[1]));
zTextView.setText(String.valueOf(value[2]));
//x = Integer.parseInt(value[0]);
//y = Integer.parseInt(value[1]);
//z = Integer.parseInt(value[2]);
LineData data = mChart.getLineData();
if (data != null) {
for (int i = 0; i < 3; i++) {
ILineDataSet set = data.getDataSetByIndex(i);
if (set == null) {
set = createSet(names[i], colors[i]);
data.addDataSet(set);
}
data.addEntry(new Entry(set.getEntryCount(),Float.parseFloat(value[i])), i);
data.notifyDataChanged();
}
mChart.notifyDataSetChanged();
mChart.setVisibleXRangeMaximum(50);
mChart.moveViewToX(data.getEntryCount());
}
}
private LineDataSet createSet(String label, int color) {
LineDataSet set = new LineDataSet(null, label);
set.setLineWidth(2.5f);
set.setColor(color);
set.setDrawCircles(false);
set.setDrawValues(false);
return set;
}
}
package com.example.matu_mio.graphdraw; import android.app.ActionBar; import android.app.Activity; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; 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.wearable.MessageApi; import com.google.android.gms.wearable.MessageEvent; import com.google.android.gms.wearable.Wearable; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.data.LineData; import com.github.mikephil.charting.data.LineDataSet; import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, MessageApi.MessageListener{ private static final String TAG = MainActivity.class.getName(); private GoogleApiClient mGoogleApiClient; TextView xTextView; TextView yTextView; TextView zTextView; LineChart mChart; int x,y,z; String[] names = new String[]{"x-value", "y-value", "z-value"}; int[] colors = new int[]{Color.RED, Color.GREEN, Color.BLUE}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); xTextView = (TextView)findViewById(R.id.xValue); yTextView = (TextView)findViewById(R.id.yValue); zTextView = (TextView)findViewById(R.id.zValue); ActionBar ab = getActionBar(); //ab.hide(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "onConnectionFailed:" + connectionResult.toString()); } }) .addApi(Wearable.API) .build(); mChart = (LineChart) findViewById(R.id.lineChart); mChart.setDescription(null); // 表のタイトルを空にする mChart.setData(new LineData()); // 空のLineData型インスタンスを追加 } @Override protected void onStart() { super.onStart(); mGoogleApiClient.connect(); } @Override protected void onStop() { super.onStop(); if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) { Wearable.MessageApi.removeListener(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. //getMenuInflater().inflate(R.menu.my, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //if (id == R.id.action_settings) { // return true; //} return super.onOptionsItemSelected(item); } @Override public void onConnected(Bundle bundle) { Log.d(TAG, "onConnected"); Wearable.MessageApi.addListener(mGoogleApiClient, this); } @Override public void onConnectionSuspended(int i) { Log.d(TAG, "onConnectionSuspended"); } @Override public void onMessageReceived(MessageEvent messageEvent) { xTextView.setText(messageEvent.getPath()); String msg = messageEvent.getPath(); String[] value = msg.split(",", 0); xTextView.setText(String.valueOf(value[0])); yTextView.setText(String.valueOf(value[1])); zTextView.setText(String.valueOf(value[2])); //x = Integer.parseInt(value[0]); //y = Integer.parseInt(value[1]); //z = Integer.parseInt(value[2]); LineData data = mChart.getLineData(); if (data != null) { for (int i = 0; i < 3; i++) { ILineDataSet set = data.getDataSetByIndex(i); if (set == null) { set = createSet(names[i], colors[i]); data.addDataSet(set); } data.addEntry(new Entry(set.getEntryCount(),Float.parseFloat(value[i])), i); data.notifyDataChanged(); } mChart.notifyDataSetChanged(); mChart.setVisibleXRangeMaximum(50); mChart.moveViewToX(data.getEntryCount()); } } private LineDataSet createSet(String label, int color) { LineDataSet set = new LineDataSet(null, label); set.setLineWidth(2.5f); set.setColor(color); set.setDrawCircles(false); set.setDrawValues(false); return set; } }
package com.example.matu_mio.graphdraw;

import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
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.wearable.MessageApi;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Wearable;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;

public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, MessageApi.MessageListener{
    private static final String TAG = MainActivity.class.getName();
    private GoogleApiClient mGoogleApiClient;
    TextView xTextView;
    TextView yTextView;
    TextView zTextView;
    LineChart mChart;
    int x,y,z;

    String[] names = new String[]{"x-value", "y-value", "z-value"};
    int[] colors = new int[]{Color.RED, Color.GREEN, Color.BLUE};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        xTextView = (TextView)findViewById(R.id.xValue);
        yTextView = (TextView)findViewById(R.id.yValue);
        zTextView = (TextView)findViewById(R.id.zValue);
        ActionBar ab = getActionBar();
        //ab.hide();
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult connectionResult) {
                        Log.d(TAG, "onConnectionFailed:" + connectionResult.toString());
                    }
                })
                .addApi(Wearable.API)
                .build();
        mChart = (LineChart) findViewById(R.id.lineChart);

        mChart.setDescription(null); // 表のタイトルを空にする
        mChart.setData(new LineData()); // 空のLineData型インスタンスを追加

    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
            Wearable.MessageApi.removeListener(mGoogleApiClient, this);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.my, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //if (id == R.id.action_settings) {
        //    return true;
        //}
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.d(TAG, "onConnected");
        Wearable.MessageApi.addListener(mGoogleApiClient, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG, "onConnectionSuspended");

    }

    @Override
    public void onMessageReceived(MessageEvent messageEvent) {
        xTextView.setText(messageEvent.getPath());
        String msg = messageEvent.getPath();
        String[] value = msg.split(",", 0);

        xTextView.setText(String.valueOf(value[0]));
        yTextView.setText(String.valueOf(value[1]));
        zTextView.setText(String.valueOf(value[2]));

        //x =  Integer.parseInt(value[0]);
        //y =  Integer.parseInt(value[1]);
        //z =  Integer.parseInt(value[2]);


        LineData data = mChart.getLineData();
        if (data != null) {
            for (int i = 0; i < 3; i++) {
                ILineDataSet set = data.getDataSetByIndex(i);
                if (set == null) {
                    set = createSet(names[i], colors[i]);
                    data.addDataSet(set);
                }

                data.addEntry(new Entry(set.getEntryCount(),Float.parseFloat(value[i])), i);
                data.notifyDataChanged();
            }

            mChart.notifyDataSetChanged();
            mChart.setVisibleXRangeMaximum(50);
            mChart.moveViewToX(data.getEntryCount());
        }
    }
    private LineDataSet createSet(String label, int color) {
        LineDataSet set = new LineDataSet(null, label);
        set.setLineWidth(2.5f);
        set.setColor(color);
        set.setDrawCircles(false);
        set.setDrawValues(false);

        return set;
    }
}

activity_main.xml(mobile)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.matu_mio.graphdraw.MainActivity">
<com.github.mikephil.charting.charts.LineChart
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lineChart"/>
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/xValue"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/yValue"
android:layout_below="@+id/xValue"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zValue"
android:layout_below="@+id/yValue"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.matu_mio.graphdraw.MainActivity"> <com.github.mikephil.charting.charts.LineChart android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/lineChart"/> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/xValue" android:layout_below="@+id/textView" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/yValue" android:layout_below="@+id/xValue" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:text="TextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/zValue" android:layout_below="@+id/yValue" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.matu_mio.graphdraw.MainActivity">


    <com.github.mikephil.charting.charts.LineChart
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/lineChart"/>


    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/xValue"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/yValue"
        android:layout_below="@+id/xValue"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:text="TextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/zValue"
        android:layout_below="@+id/yValue"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</android.support.constraint.ConstraintLayout>

 

参考

Android:グラフ表示で表現豊かに。MPAndroidChart を使ってみよう!|マネーフォワード エンジニアブログ

MPAndroidChartを使って「リアルタイム更新のセンサーデータ時系列グラフ」のサンプルを作ってみた|LyricalMaestro0-Qiita

 

  • このエントリーをはてなブックマークに追加
  • Pocket

SNSでもご購読できます。

コメント

  1. ゆんきち より:

    こんにちは。このAndroidWear側のアプリは公開されていますか?
    またweb bluetooth apiからその値を取得することはできるものなのでしょうか?

    1. mio より:

      ゆんきちさん
      コメントありがとうございます。
      こちらのアプリについては公開しておらず、本記事に掲載しているソースコードのみとなっております。
      また、Web Bluetooth APIについては本サンプルで使用しておらず、申し訳ございませんが分かりかねます。

コメントを残す

*

CAPTCHA