Android(X06HT Desire) 搭載センサーの値を取得してみる

実機を使ってデバッグすることを覚えたので、Desire に搭載されているセンサーの値を取得してみよう。

http://developer.android.com/reference/android/hardware/SensorEvent.html

SenserEvent API の座標系

desire 

OpenGLの座標系と同じであり、一般のコンピューター上のスクリーン座標(左上が原点)とは異なる。

3軸 加速度センサー(3-axis Accelerometer)

 

accel

m/s2(メートル毎秒毎秒)で、加速度を表す。

加速度の計測

  1. X軸加速度
  2. Y軸加速度
  3. Z軸加速度
  • 水平なテーブルに端末を置いて、左側を右に向けて押した場合、X軸加速度は、正の値になる。
  • 水平なテーブルに端末を置いた場合、加速度の値は、端末の加速度(0 m/s^2) 引く、重力(-9.81 m/s^2)で、 +9.81 となる。
  • 水平なテーブルに端末を置いて、空に向けて A m/s^2 の加速度をかけた場合、A + 9.81 となる。

3軸 磁界センサー(3-axis Magnetic field sensor)

magnetic 

磁界センサーは、いろいろな用途に利用できるようだが、自分にはさっぱり理解できません。

μT(マイクロテスラ)という単位で電磁波をはかるらしい。

某ピップエレキバンの類似商品が、うちにあり、パッケージを見ると 「100マイクロテスラ」 とうたっている。

pip

Desire の背面の左下あたりに近づけると、確かに 100マイクロテスラ を超える値を検知!

某エレキバンの真偽を確かめるのには使えそうだ。

傾きセンサー(Orientation sensor)

orientation

  1. 方位 ・・・ 0=北, 90=東, 180=南, 270=西 として、0 ~ 359 の角度
  2. ピッチ(Pitch) ・・・ X軸にそって、-180 ~ 180 まで回転。Z軸が、Y軸に向かう場合、正の値。
  3. ロール(Roll) ・・・ Y軸にそって、 -90 ~ 90 まで回転。X軸が、Z軸に向かう場合、正の値。

orientation

近接センサー(Proximity sensor)

proximity

物体が近づいたら距離を cm で検知する。

ただし、上記に対応しておらず、「近い」「遠い」のいずれかで計測するものもある。

Desire では、近い 0 、遠い 1 と計測されるようだ。

輝度センサー(Light sensor)

light

明るさをルクス(lux)で計測

 

上記のソースコード。

package info.typea.sensorlist;
package info.typea.sensorlist;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class SensorListActivity extends ListActivity {

    private final static String ACTIVE_SENSOR = "ActiveSensor";
    private SensorManager sensorManager = null;
    
    private List<SensorItem> sensorItems;
    private TextView txtResult = null;
    
    private int activeSensorType = 0;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        sensorManager = (SensorManager)this.getSystemService(SENSOR_SERVICE);
        List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
        
        sensorItems = new ArrayList<SensorItem>();
        for (Sensor sensor : sensors) {
            SensorItem sensorItem = new SensorItem();
            sensorItem.setSensorName(sensor.getName());
            sensorItem.setSensorType(sensor.getType());
            sensorItems.add(sensorItem);
        }
        ArrayAdapter<SensorItem> lstAdapter 
            = new ArrayAdapter<SensorItem>(this, R.layout.sensor_row, sensorItems);
        setListAdapter(lstAdapter);
    
        txtResult = (TextView) findViewById(R.id.txt_result);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        
        // プリファレンスに保存されたセンサーを復帰
        SharedPreferences pref = getPreferences(MODE_PRIVATE);
        int sensorType = pref.getInt(ACTIVE_SENSOR, 0);
        startSensorTrace(sensorType);
    }
    
    @Override
    protected void onPause() {
        
        // 選択されたセンサーをプリファレンスに待避
        if (this.activeSensorType != 0) {
            SharedPreferences pref = getPreferences(MODE_PRIVATE);
            Editor editor = pref.edit();
            editor.putInt(ACTIVE_SENSOR, this.activeSensorType);
            editor.commit();
        }
        super.onPause();
    }
    
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
    
        txtResult.setText("");
        
        // 選択されたセンサーのリスニングを行う
        int sensorType = ((SensorItem)l.getAdapter().getItem(position)).getSensorType();
        startSensorTrace(sensorType);
    }
        
    /**
     * センサータイプを指定してリスナーを登録
     * 指定されなかったセンサーのリスナーの登録解除
     * @param sensorType
     */
    private void startSensorTrace(int sensorType) {
        ListAdapter lstAdapter = this.getListAdapter();
        for (int i=0; i<lstAdapter.getCount(); i++) {
            SensorItem sensorItem = (SensorItem)lstAdapter.getItem(i);
            if (sensorItem.getSensorType() == sensorType) {
                Sensor sensor =    sensorManager.getDefaultSensor(sensorItem.getSensorType());
                // センサーリスニングの登録
                sensorManager.registerListener(
                        sensorItem.listener,sensor, SensorManager.SENSOR_DELAY_NORMAL);
                this.activeSensorType = sensorType;
            } else {
                // センサーリスニングの登録解除
                sensorManager.unregisterListener(sensorItem.listener);
            }
        }
    }
    
    /**
     * 加速度センサー
     */
    class AccelerometerSensorListner implements SensorEventListener {
        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
        }
        @Override
        public void onSensorChanged(SensorEvent event) {
            String r = String.format(
                        "--------------------------------\n" + 
                        "3-axis Accelerometer\n"+
                        "--------------------------------\n" +
                        "minus Gx on the x-axis : %f\n" +
                        "minus Gy on the y-axis : %f\n" +
                        "minus Gz on the z-axis : %f"
                        ,event.values[0]
                        ,event.values[1]
                        ,event.values[2]
                      );
            txtResult.setText(r);
        }
    }
    /**
     * 傾きセンサー 
     * @see SensorManager.getOrientation()
     */
    class OrientationSensorListener implements SensorEventListener {
        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
        }
        @Override
        public void onSensorChanged(SensorEvent event) {
            String r = String.format(
                    "--------------------------------\n" + 
                    "Orientation sensor\n"+
                    "--------------------------------\n" +
                    "Azimuth(0=N,90=E,180=S,270=W) : %f\n" +
                    "Pitch (X axis -180 to 180) : %f\n" +
                    "Roll (Y axis -90 to 90) : %f"
                    ,event.values[0]
                    ,event.values[1]
                    ,event.values[2]
                  );
            txtResult.setText(r);
        }
    }
    /**
     * 磁界センサー 
     */
    class MagneticFieldSensorListener implements SensorEventListener {
        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
        }
        @Override
        public void onSensorChanged(SensorEvent event) {
            String r = String.format(
                    "--------------------------------\n" + 
                    "3-axis Magnetic field sensor\n"+
                    "--------------------------------\n" +
                    "X axis : %f μT\n" +
                    "Y axis : %f μT\n" +
                    "Z axis : %f μT"
                    ,event.values[0]
                    ,event.values[1]
                    ,event.values[2]
                  );
            txtResult.setText(r);
        }
    }
    
    /**
     * 輝度センサー
     */
    class LightSensorListener implements SensorEventListener {
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
            String r = String.format(
                    "--------------------------------\n" + 
                    "light sensor\n"+
                    "--------------------------------\n" +
                    "%f lux"
                    ,event.values[0]
                  );
            txtResult.setText(r);
        }
    }
    
    /**
     * 近接センサー
     */
    class ProximitySensorListener implements SensorEventListener {
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
            String r = String.format(
                    "--------------------------------\n" + 
                    "proximity sonsor\n"+
                    "--------------------------------\n" +
                    "%f cm"
                    ,event.values[0]
                  );
            txtResult.setText(r);
        }
        
    }
    
    /**
     * @see http://developer.android.com/reference/android/hardware/SensorEvent.html
     */
    class SensorItem {
        private int sensorType;
        private String sensorName;
        public SensorEventListener listener;
        
        public int getSensorType() {
            return sensorType;
        }

        /**
         * センサーごとにリスナーを生成
         * @param sensorType
         */
        public void setSensorType(int sensorType) {
            this.sensorType = sensorType;
            
            switch(this.sensorType) {
            case Sensor.TYPE_ACCELEROMETER:
                this.listener = new AccelerometerSensorListner();
                break;
            case Sensor.TYPE_ORIENTATION:
                this.listener = new OrientationSensorListener();
                break;
            case Sensor.TYPE_MAGNETIC_FIELD:
                this.listener = new MagneticFieldSensorListener();
                break;
            case Sensor.TYPE_LIGHT:
                this.listener = new LightSensorListener();
                break;
            case Sensor.TYPE_PROXIMITY:
                this.listener = new ProximitySensorListener();
                break;
            default:
                this.listener = new SensorEventListener() {
                    @Override
                    public void onSensorChanged(SensorEvent event) {
                    }
                    @Override
                    public void onAccuracyChanged(Sensor sensor, int accuracy) {
                        txtResult.setText("No Sensor Listener.");
                    }
                };
                break;
            }
        }
        public String getSensorName() {
            return sensorName;
        }
        public void setSensorName(String sensorName) {
            this.sensorName = sensorName;
        }
        @Override
        public String toString() {
            return getSensorName();
        }
    }
}