ウェアラブル時代に見直したいAndroidの加速度/重力センサー、ジャイロスコープAndroidで動く携帯Javaアプリ作成入門(51)(1/3 ページ)

IoT/ウェアラブル時代に見直したいセンシング技術。Androidがサポートするセンサー一覧や基本的なセンサーアプリの作り方を解説します。

» 2014年05月22日 18時00分 公開
[緒方聡株式会社イーフロー]

IoT/ウェアラブル時代到来――Androidのセンシング技術を見直そう

「Androidで動く携帯Javaアプリ開発入門」のインデックス

連載目次

 最近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は以下のセンサーをサポートします。

表1 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を使用しているのは、センサーのイベント通知を描画処理で遅くしないようにしたいためです。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。