IoT/ウェアラブル時代に見直したいセンシング技術。Androidがサポートするセンサー一覧や基本的なセンサーアプリの作り方を解説します。
最近IoT(Internet of Things:モノのインターネット)という言葉が流行し、センシング技術が注目を集めています(参考:Arduinoで始めるWeb技術者のためのIoT入門)。
また2014年3月に、米グーグルがAndroidプラットフォームをウェアラブル端末に拡張するプロジェクト「Android Wear」を発表しました(参考:「Android Wear」のデベロッパープレビュー公開、Oculus Riftの新開発キットも)。すでに、LGエレクトロニクスやモトローラがAndroid Wear対応端末を発表しています。
ウェアラブル端末でもヘルスケアの観点からセンシング技術が重要な位置付けになることが予想されます(参考:ウェアラブルデバイスとビッグデータのすてきな関係?)。
センシング技術といえば、Androidでも以前からサポートしているものが多数あります。Androidは、スマートフォンだけではなく、すでに組み込みデバイスにも採用されて、いろいろなところで使われています。IoT/ウェアラブル端末が注目を浴びる中、Androidのセンシング技術も注目されているようです。
Androidのセンサーについては、本連載「Androidで動く携帯Javaアプリ作成入門」でも第13回の「iPhoneより多彩なAndroidのセンサをアプリで操作」で取り上げていますが、この記事は2010年1月、Android 2.1が登場、という時期の記事です。内容として、現在でも通用する部分はあるものの、その後非推奨になっているセンサーがあったり、増えたセンサーがあったりします。
そこで今回から数回に分けてAndroid 4.xのセンサーの取り扱い方について解説していきます。初回はAndroidでセンサーを扱うための基本と、スマートフォンやウェアラブル端末でよく使われる加速度センサー、重力センサー、ジャイロスコープを例にアプリで使う方法について解説します。
現段階でAndroidは以下のセンサーをサポートします。
種類 | センサータイプ(定数) | Android 4.4 | 4.0 | 2.3 | 2.2 | 1.5 |
---|---|---|---|---|---|---|
加速度 | TYPE_ACCELEROMETER | Yes | Yes | Yes | Yes | Yes |
周辺温度 | TYPE_AMBIENT_TEMPERATURE | Yes | Yes | N/A | N/A | N/A |
重力 | TYPE_GRAVITY | Yes | Yes | Yes | N/A | N/A |
ジャイロスコープ | TYPE_GYROSCOPE | Yes | Yes | Yes | N/A※1 | N/A※1 |
輝度(照度) | TYPE_LIGHT | Yes | Yes | Yes | Yes | Yes |
重力加速度を除いた加速度 | TYPE_LINEAR_ACCELERATION | Yes | Yes | Yes | N/A | N/A |
磁界(磁気) | TYPE_MAGNETIC_FIELD | Yes | Yes | Yes | Yes | Yes |
方位 | TYPE_ORIENTATION | Yes※2 | Yes※2 | Yes※2 | Yes※2 | Yes |
気圧 | TYPE_PRESSURE | Yes | Yes | Yes | N/A※1 | N/A※1 |
近接 | TYPE_PROXIMITY | Yes | Yes | Yes | Yes | Yes |
湿度 | TYPE_RELATIVE_HUMIDITY | Yes | Yes | N/A | N/A | N/A |
回転ベクトル | TYPE_ROTATION_VECTOR | Yes | Yes | Yes | N/A | N/A |
ステップカウンター | TYPE_STEP_COUNTER | Yes | N/A | N/A | N/A | N/A |
ステップ感知 | TYPE_STEP_DETECTOR | Yes | N/A | N/A | N/A | N/A |
温度 | TYPE_TEMPERATURE | Yes※2 | Yes※2 | Yes | Yes | Yes |
※1 このセンサータイプはAndroid 1.5で追加されましたが、Android 2.3まで使用できません ※2 このセンサーは利用可能ですが非推奨になりました |
この表にはTYPE_GAME_ROTATION_VECTORなどの、他のセンサーと同一でタイプのみ異なるものは含んでいないので、注意してください。全てのセンサータイプが知りたい場合はSensorのJavadocを参照してください。
センサーの概要や挙動、仕様に関しては、以下のドキュメントに目を通しておくことをお勧めします。
特に、センサーが通知してくる値の意味に関する説明がJavadocと詳細説明に詳しく解説されているので、目を通しておくとよいでしょう。
さて、今回のサンプルアプリは以下よりダウンロード可能です。
本連載では、いつもはサンプルアプリを作成するに当たり、できるだけシンプルに分かりやすく実装するように心掛けていますが、今回のサンプルアプリは、たくさんあるセンサーの確認を行うActivityを効率良く実装できるようにすることに重きを置いています。
ここからは、サンプルアプリの構成について説明します。
Androidのセンサーは、以下のような使い方をするものがほとんどです。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(); // SensorManagerを取得 mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); } @Override protected void onResume() { super.onResume(); // センサータイプを指定してセンサーを取得 Sensor sensor = mSensorManager.getDefaultSensor(...); // SensorManagerにリスナーを登録 mSensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_FASTEST); } @Override protected void onPause() { super.onPause(); // 登録したリスナーを解除 mSensorManager.unregisterListener(listener); } @Override public void onSensorChanged(SensorEvent event) { // センサーから値の変更通知があったらvaluesの値を解析 float[] values = event.values; …… }
今回のサンプルでは、複数のセンサーでこのような同一処理を抽象化・共通化して実装をスッキリさせるようにしています。センサーの値を画面に何らかの形で表示する必要もあるため、その部分も抽象化・共通化しています。
以下は通常のセンサーの使い方を抽象化した今回のサンプルに含まれるActivityです。
public abstract class AbstractSensorActivity extends Activity implements SensorEventListener { protected SensorManager mSensorManager; protected AbstractSensorView mView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); // 抽象化されたViewをサブクラスから取得して設定 mView = getSensorView(this); setContentView(mView); } @Override protected void onResume() { super.onResume(); // サブクラスからタイプを取得してセンサーを取得 Sensor sensor = mSensorManager.getDefaultSensor(getSensorType()); mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST); } @Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { Toast.makeText(this, Utils.onAccuracyChangedHelper(sensor, accuracy), Toast.LENGTH_LONG).show(); } @Override public void onSensorChanged(SensorEvent event) { mView.onValueChanged(event.values); } // サブクラスからセンサー確認用のViewを取得 abstract AbstractSensorView getSensorView(Context context); // サブクラスからセンサータイプを取得 abstract int getSensorType(); }
これ以外にも画面表示共通処理の抽象化をSurfaceViewのサブクラスで行っています。わざわざSurfaceViewを使用しているのは、センサーのイベント通知を描画処理で遅くしないようにしたいためです。
Copyright © ITmedia, Inc. All Rights Reserved.