センサー (1) 光センサーと加速度センサー ================================================================================ 各種センサーを使うことができる。 ■ センサーのタイプ Sensor クラスの定数で定義してある。以下にまとめる。 センサー名 定数 単位 値の次元 可 ------------------- --------------------------- ------- -------- ------ 加速度 TYPE_ACCELEROMETER m/s^2 3 ○ 重力 TYPE_GRAVITY m/s^2 3 ※ ジャイロスコープ TYPE_GYROSCOPE rad/s 3 × 光 TYPE_LIGHT lux 1 ○ 線形加速 TYPE_LINEAR_ACCELERATION m/s^2 3 ※ 地磁気 TYPE_MAGNETIC_FIELD 3 ○ 圧力 TYPE_PRESSURE Pa 1 × 近接 TYPE_PROXIMITY cm 1 ○ 回転ベクトル TYPE_ROTATION_VECTOR - 4 ※ 温度 TYPE_TEMPERATURE ℃ 1 ○ 傾き TYPE_ORIENTATION deg 3 非推奨 (○あり、×なし、※Android2.2では対象外) ■ センサーのタイプと値の取得方法 センサーの値を取得するには、つぎの手順が必要。 1. SensorManager のオブジェクトを取得する 2. SensorManager オブジェクトにセンサーのリスナーを登録する 3. センサーの値を取得する ここでは、値の取得について補足する。 どのセンサーでも、センサーのリスナーの void onSensorChanged(SensorEvent event) メソッドの event に、そのときの値が入っている。これのインスタンス変数 values が 配列になっており、センサーからの取得値の次元によって、要素数が決まる。 以下にそれぞれのセンサーについての values について補足する。 □ TYPE_ACCELEROMETER 加速度センサー values[0]: X 軸方向の加速度 values[1]: Y 軸方向の加速度 values[2]: Z 軸方向の加速度 X 軸: 実機の横方向(右方向が正) Y 軸: 実機のたて方向(上方向が正) Z 軸: 実機の前面方向(前面方向が正) SensorEvent クラスの API に図入りで説明がある。 □ TYPE_GRAVITY 重力センサー ※Android2.2 にはない □ TYPE_GYROSCOPE ジャイロスコープ・センサー values[0]: X 軸方向の角速度 values[1]: Y 軸方向の角速度 values[2]: Z 軸方向の角速度 □ TYPE_LIGHT 光センサー values[0]: 照度 □ TYPE_LINEAR_ACCELERATION 線形加速センサー ※Android2.2 にはない □ TYPE_MAGNETIC_FIELD 地磁気センサー values[0]: X 軸方向の磁気密度 values[1]: Y 軸方向の磁気密度 values[2]: Z 軸方向の磁気密度 □ TYPE_PRESSURE 圧力センサー □ TYPE_PROXIMITY 近接センサー values[0]: 距離 □ TYPE_ROTATION_VECTOR 回転ベクトル・センサー ※Android2.2 にはない □ TYPE_TEMPERATURE 温度センサー APIには特に記述はないが、摂氏で取得される。 □ TYPE_ORIENTATION 傾きセンサー ただし、この定数は非推奨になったので、このセンサーの値は、この定数を使うのではな く、SensorManager.getOrientation() メソッドを使う。 ■ 光センサーの値を表示する 光センサーの値を取得して、表示する。 単位: lux (ルクス) values[0]: 照度 センサーの値を取得するには、つぎの手順が必要。 1. SensorManager のオブジェクトを取得する 2. SensorManager オブジェクトにセンサーのリスナーを登録する 3. センサーの値を取得する これにしたがって、プログラムを作る。 □ LightSensor01Activity.java --- package jp.marunomaruno.android.sample; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; /** * 光センサーの値を表示する。 * @author marunomaruno * @version 1.0, 2011-06-25 */ public class LightSensor01Activity extends Activity { // TextView private TextView lightTextView; // 光センサー private SensorManager sensorManager; // (1) private SensorEventListener sensorEventListener; // onPause()が呼ばれたときに、すべてのリスナーを解除するため // (2) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lightTextView = (TextView) findViewById(R.id.sensor_value); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);// (3) } @Override protected void onResume() { super.onResume(); // 光センサーを取得して登録する sensorEventListener = new LightSensorListener(lightTextView); // (4) for (Sensor sensor : sensorManager.getSensorList(Sensor.TYPE_LIGHT)) {// (5) sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); // (6) } } @Override public void onPause() { // (7) super.onPause(); // すべてのリスナーを解除する sensorManager.unregisterListener(sensorEventListener); // (8) } } --- (1)(3) SensorManager を宣言する。 private SensorManager sensorManager; // (1) sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);// (3) SensorManager は、センサーにアクセスするためのクラス。 ・クラス階層 java.lang.Object + android.hardware.SensorManager public なコンストラクターはない。オブジェクトの取得は、(3) のように、 getSystemService(SENSOR_SERVICE) を使う。 実際は、 Context.getSystemService(Context.SENSOR_SERVICE) だが、Activity クラスのサブクラスの中から取得しているため、「Context.」部分は必 要ない。 ・主なメソッド --- List<Sensor> getSensorList(int type) boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler) boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) void unregisterListener(SensorEventListener listener, Sensor sensor) void unregisterListener(SensorEventListener listener) --- メソッドとしては、次のような使い方の構成になっている。 ・Android 実機から、使えるセンサーのリストを getSensorList() メソッドで取得する。 ・それを、registerListener() メソッドを使って、センサーと、そのリスナーとを紐付 ける。 ・センサーが必要なくなったら、unregisterListener() で、紐付けを解除する。 (2)(8) onPause()が呼ばれたときに、すべてのリスナーを解除するために、センサーのリ スナーを登録しておくリストを宣言する。 private SensorEventListener sensorEventListener; // onPause()が呼ばれたときに、すべてのリスナーを解除するため // (2) リスナーの解除は、(8) にあるように、SensorManager クラスの unregisterListener(listener) メソッドを使う。 sensorManager.unregisterListener(sensorEventListener); // (8) (4) 光センサーのリスナーを宣言する sensorEventListener = new LightSensorListener(lightTextView); // (4) 光センサー・リスナーは、別クラスとして作っている。 別クラスとして作ることで、単体テストなどはしやすくなる。また、他のアプリケーショ ンでの再利用もしやすくなる利点がある。 (5) for (Sensor sensor : sensorManager.getSensorList(Sensor.TYPE_LIGHT)) {// (5) 光センサーのディバイスを取得する。1台の実機に、複数の光センサーがついている可能 性があるので、戻り値はリストになっている。 List<Sensor> getSensorList(int type) 引数の type は、センサーの種類を表す定数で、Sensor クラスに、つぎのような定数が 定義されている。 センサー名 定数 単位 値の次元 可 ------------------- --------------------------- ------- -------- ------ 加速度 TYPE_ACCELEROMETER m/s^2 3 ○ 重力 TYPE_GRAVITY m/s^2 3 ※ ジャイロスコープ TYPE_GYROSCOPE rad/s 3 × 光 TYPE_LIGHT lux 1 ○ 線形加速 TYPE_LINEAR_ACCELERATION m/s^2 3 ※ 地磁気 TYPE_MAGNETIC_FIELD 3 ○ 圧力 TYPE_PRESSURE Pa 1 × 近接 TYPE_PROXIMITY cm 1 ○ 回転ベクトル TYPE_ROTATION_VECTOR - 4 ※ 温度 TYPE_TEMPERATURE ℃ 1 ○ 傾き TYPE_ORIENTATION deg 3 非推奨 (○あり、×なし、※Android2.2では対象外) また、TYPE_ALL という定数があり、これですべてのセンサーのオブジェクトを取得でき る。 Sensor クラス ・クラス階層 java.lang.Object + android.hardware.Sensor ・主なメソッド --- float getMaximumRange() int getMinDelay() String getName() float getPower() float getResolution() int getType() String getVendor() int getVersion() --- (6) センサーのリスナーをセンサーに登録する sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); // (6) つぎのメソッドがある。 --- boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler) boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) --- 今回は、光センサーに、光センサーのリスナーを登録する。登録は、紐付けしていること になる。 rate は、SensorManager クラスでつぎの 4 つの定数が定義されている。 SENSOR_DELAY_NORMAL, SENSOR_DELAY_UI, SENSOR_DELAY_GAME, SENSOR_DELAY_FASTEST これらは、定数の値としては 3, 2, 1, 0 なので、直接遅延時間になっているわけではな い。 実際の遅延時間の値を確認するには、Sensor クラスに int getMinDelay() があるが、これは API レベル 9 なので、Android2.2 では使えない。 SensorManager クラスのソースで見てみると、次のような値になっている(実際はμ秒 値)。 SENSOR_DELAY_FASTEST 0 ms ( 0 μs) SENSOR_DELAY_GAME 20 ms ( 20000 μs) SENSOR_DELAY_UI 60 ms ( 60000 μs) SENSOR_DELAY_NORMAL 200 ms (200000 μs) そして、0~3 以外の値であれば、その値が直接遅延時間として採用される。 (7)(8) アクティビティがバックグランドに隠れる直前に、センサーのリスナーを解除す る public void onPause() { // (7) onPause() メソッドは、アクティビティがバックグランドに隠れる直前(他のアクティビ ティが起動、たとえば、着信があった、電話をかける)に呼ばれる。 センサーが動いていれば、その分、電池が消耗するので、隠れるときにはセンサーをいっ たん停止させる。 sensorManager.unregisterListener(sensorEventListener); // (8) 解除には、 void unregisterListener(SensorEventListener listener, Sensor sensor) void unregisterListener(SensorEventListener listener) を使う。sensor の指定がなければ、リスナーが登録されているすべてのセンサーから解 除する。 □ LightSensorListener.java --- package jp.marunomaruno.android.sample; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.widget.TextView; /** * 光センサーのリスナー * @author maruno * @version 1.0, 2011-06-23 * @since 1.0 */ public class LightSensorListener implements SensorEventListener { // (1) protected TextView textView; public LightSensorListener(TextView textView) { this.textView = textView; } @Override public void onSensorChanged(SensorEvent event) { // (2) // 値を取得する float x = event.values[0]; // (3) // TextViewに表示する textView.setText(String.format( textView.getResources().getString(R.string.sensor_value_format), textView.getResources().getString(R.string.light), event.sensor.getName(), x, textView.getResources().getString(R.string.lightUnit) )); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // (4) assert true; // 何もしない } } --- (1) 光センサーのリスナーの定義 public class LightSensorListener implements SensorEventListener { // (1) センサーに変化があったときに使うリスナー・クラスを定義する。 SensorEventListener センサーの値が変わったときに呼び出されるリスナーのインターフェース ・メソッド --- abstract void onAccuracyChanged(Sensor sensor, int accuracy) センサーの精度が変わったとき abstract void onSensorChanged(SensorEvent event) センサーからの値が変わったとき --- (2)(3) センサーの値が変化したときに呼ばれるハンドラー・メソッドとそのときの値の取 得 public void onSensorChanged(SensorEvent event) { // (2) float x = event.values[0]; // (3) 引数の event から、値を取得する。 光センサーは、1次元の値を取得するので、values は、要素数 1 である。 SensorEvent センサーから生成されたイベントを表すクラス。 ・クラス階層 java.lang.Object + android.hardware.SensorEvent ・public フィールド --- public int accuracy 精度 public Sensor sensor このイベントを生成したセンサー public long timestamp イベントが起きたタイムスタンプ public final float[] values 値。配列の長さは、値の次元数 --- (4) センサーの精度が変更されると呼ばれるハンドラー・メソッド public void onAccuracyChanged(Sensor sensor, int accuracy) { // (4) 通常は、このメソッドが使われることはない(らしい)。 □ res/layout/main.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- センサー値 --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/light" android:id="@+id/sensor_value" /> </LinearLayout> --- □ res/values/strings.xml --- <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">LightSensor01</string> <string name="light">光</string> <string name="lightUnit">lux</string> <string name="sensor_value_format">%1$s: %2$s = %3$.2f (%4$s)</string> </resources> --- センサーの値は、次の形式で表示する。 センサー名: オブジェクトの情報 = 値 (単位) ■ 加速度センサーの値を表示する 加速度センサーの値を取得して、表示する。 加速度センサーは、3 次元の値として取得する。単位は、m/s^2。 値は、SensorEvent の次のフィールドを使って取得する。 values[0]: X 軸方向の加速度 values[1]: Y 軸方向の加速度 values[2]: Z 軸方向の加速度 X 軸: 実機の横方向(右方向が正) Y 軸: 実機のたて方向(上方向が正) Z 軸: 実機の前面方向(前面方向が正) なお、SensorEvent クラスの API に図入りで説明がある。 □ AcceleraterSensor01Activity.java --- package jp.marunomaruno.android.sample; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; /** * 加速度センサーの値を表示する。 * * @author marunomaruno * @version 1.0, 2011-06-25 */ public class AcceleraterSensor01Activity extends Activity { // TextView private TextView acceleraterTextView; // 加速度センサー private SensorManager sensorManager; private SensorEventListener sensorEventListener; // onPause()が呼ばれたときに、すべてのリスナーを解除するため @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); acceleraterTextView = (TextView) findViewById(R.id.sensor_value); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); } @Override protected void onResume() { super.onResume(); // 加速度センサーを取得して登録する sensorEventListener = new AcceleraterSensorListener( acceleraterTextView); // (1) for (Sensor sensor : sensorManager.getSensorList( Sensor.TYPE_ACCELEROMETER)) { // (2) sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); } } @Override public void onPause() { super.onPause(); // すべてのリスナーを解除する sensorManager.unregisterListener(sensorEventListener); } } --- (1)(2) 加速度センサーを取得して登録 sensorEventListener = new AcceleraterSensorListener(acceleraterTextView); // (1) 加速度センサーのオブジェクトを生成する。 for (Sensor sensor : sensorManager.getSensorList( Sensor.TYPE_ACCELEROMETER)) { // (2) 加速度センサーのデバイスのオブジェクトを取得する。これには、定数 TYPE_ACCELEROMETER を使う。 □ AcceleraterSensorListener.java --- package jp.marunomaruno.android.sample; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.widget.TextView; /** * 加速度センサーのリスナー * @author maruno * @version 1.0, 2011-06-23 * @since 1.0 */ public class AcceleraterSensorListener implements SensorEventListener { protected TextView textView; public AcceleraterSensorListener(TextView textView) { this.textView = textView; } @Override public void onSensorChanged(SensorEvent event) { // 値を取得する float x = event.values[0]; // (1) float y = event.values[1]; // (2) float z = event.values[2]; // (3) // TextViewに表示する textView.setText(String.format( textView.getResources().getString(R.string.sensor_value_format), textView.getResources().getString(R.string.accelerater), event.sensor.getName(), x, y, z, textView.getResources().getString(R.string.acceleraterUnit) )); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { assert true; // 何もしない } } --- (1)(2)(3) センサーの値を取得 float x = event.values[0]; // (1) float y = event.values[1]; // (2) float z = event.values[2]; // (3) 加速度センサーは 3 次元の値を持つので、values は要素数 3 の配列になる。それぞれ、 x, y, z として取得する。 □ res/layout/main.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- センサー値 --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/accelerater" android:id="@+id/sensor_value" /> </LinearLayout> --- □ res/values/strings.xml --- <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">AcceleraterSensor01</string> <string name="accelerater">加速度</string> <string name="acceleraterUnit">m/s^2</string> <string name="sensor_value_format">%1$s: %2$s = (X, Y, Z) = (%3$.2f, %4$.2f, %5$.2f) (%6$s)</string> </resources> ---
最新の画像[もっと見る]
-
あけましておめでとうございます 11年前
-
今年もよろしくお願いいたします 12年前
-
あけましておめでとうございます 13年前
-
あけましておめでとうございます 16年前
※コメント投稿者のブログIDはブログ作成者のみに通知されます