2015-09-21

Android デバイスの加速度センサー値を取得

Android デバイスに搭載されている加速度センサーを使うと、図のように X 軸、Y 軸、Z 軸の各軸に掛かる加速度(m/s^2)を測定でき、Android デバイスの向きや動きを把握することができます。


加速度センサーの値は、以下の手順で取得できるようになります。

SensorEventListener インタフェースの実装


加速度センサーの値を取得するには MainActivitySensorEventListener インタフェースを実装します。
public class MainActivity extends Activity implements SensorEventListener {
    ...
}

SensorManager でセンサーのオブジェクトを取得


アプリでセンサーを利用するには SensorManager を取得します。SensorManager を取得したら getSensorList() メソッドで指定したセンサーのオブジェクトを取得します。具体的なセンサー値をアプリ内で利用するため onResume() メソッド内にセンサー値が変化したことを検知するリスナを登録します。
SensorManager sm;

@Override
protected void onResume() {
    super.onResume();
    sm = (SensorManager)getSystemService(SENSOR_SERVICE);
    List<Sensor> sensors =
        sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
    if (0 < sensors.size()) {
        sm.registerListener(this, sensors.get(0),
            SensorManager.SENSOR_DELAY_NORMAL);
    }
}

登録したリスナは onPause() メソッド内で解除します。
@Override
protected void onPause() {
    super.onPause();
    sm.unregisterListener(this);
}

加速度センサーの値を取得


加速度センサーの値に変化があった場合の処理を onSensorChanged() メソッド内に記述します。
@Override
public void onSensorChanged(SensorEvent event) {
    gx = event.values[0];
    gy = event.values[1];
    gz = event.values[2];
}


加速度センサーの値を表示するアプリの作成


以上を踏まえ Android デバイスに搭載されている加速度センサーから取得した値を画面に表示するアプリを作成しました。
package com.example.accelerometer;

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.os.Handler;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;
public class MainActivity extends Activity implements Runnable, SensorEventListener {
    SensorManager sm;
    TextView tv;
    Handler h;
    float gx, gy, gz;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout ll = new LinearLayout(this);
        setContentView(ll);

        tv = new TextView(this);
        ll.addView(tv);

        h = new Handler();
        h.postDelayed(this, 500);
    }

    @Override
    public void run() {
        tv.setText("X-axis : " + gx + "\n"
                 + "Y-axis : " + gy + "\n"
                 + "Z-axis : " + gz + "\n");
        h.postDelayed(this, 500);
    }

    @Override
    protected void onResume() {
        super.onResume();
        sm = (SensorManager)getSystemService(SENSOR_SERVICE);
        List<Sensor> sensors =
                sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
        if (0 < sensors.size()) {
            sm.registerListener(this, sensors.get(0),
                    SensorManager.SENSOR_DELAY_NORMAL);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        sm.unregisterListener(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        h.removeCallbacks(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        gx = event.values[0];
        gy = event.values[1];
        gz = event.values[2];
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}

アプリの実行結果


Android 実機を水平な机に、ディスプレイを上向きに寝かせて置いた時の実行結果は以下のようになりました。Z 軸方向に重力加速度(9.8 m/s^2)に近い値が取得できていることが分かります。

また、Android 実機を真っ直ぐに立てて持った場合の結果は以下のようになりました。

そこから90度左に倒すと以下のようになりました。

各軸のセンサー値が正常に取得できていることが確認できました。
取得したセンサー値を見てみると、不必要なほど分解能が高いのに対し、精度はそこまで高くないような気がします。きっと安価で小型なセンサーだと思いますので、仕方のないことかもしれません。

0 件のコメント:

コメントを投稿