C/C++プログラマの管理者が, Androidプログラムにチャレンジ. AndroidプログラミングのTipsをメモっていく予定です.

方位角や傾きを求めるのにSensor.TYPE_ORIENTATIONを使用していたが, API Level 8で非推奨になったようである.
そこで, Sensor.TYPE_MAGNETIC_FIELDとSensor.TYPE_ACCELEROMETERを使用して, 方位角と傾きを検出する.

方位角/傾きの検出

  • Sensor06.java
    • 各種センサーの使い方は, それぞれを参照.
   加速度センサーの値を取得する, 磁気センサーの値を取得する, 傾きセンサーの値を取得する
    • SensorManager#getRotationMatrixメソッドで, 加速度センサーと地磁気センサーの値から回転行列を求める.
    • SensorManager#remapCoordinateSystemメソッドで, 端末の画面設定に合わせる変換行列を求める.
    • SensorManager#getOrientationメソッドで, 方位角及び傾きを求める.
package com.moonlight_aska.android.sensor06;

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.widget.TextView;

public class Sensor06 extends Activity implements SensorEventListener {
  private SensorManager manager;
  private TextView values;
  // 回転行列
  private static final int MATRIX_SIZE = 16;
  float[] inR = new float[MATRIX_SIZE];
  float[] outR = new float[MATRIX_SIZE];
  float[] I = new float[MATRIX_SIZE];
  // センサー値
  private static final int AXIS_NUM = 3;
  float[] gravity = new float[AXIS_NUM];
  float[] geomagnetic = new float[AXIS_NUM];
  float[] orientation = new float[AXIS_NUM];
  float[] attitude = new float[AXIS_NUM];

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    values = (TextView)findViewById(R.id.value_id);
    manager = (SensorManager)getSystemService(SENSOR_SERVICE);
  }

  @Override
  protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    // Listenerの登録解除
    manager.unregisterListener(this);
  }

  @Override
  protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();

    // Listenerの登録
    manager.registerListener(this,
      manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
      SensorManager.SENSOR_DELAY_UI);
    manager.registerListener(this,
      manager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
      SensorManager.SENSOR_DELAY_UI);
    manager.registerListener(this,
      manager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
      SensorManager.SENSOR_DELAY_UI);
  }

  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // TODO Auto-generated method stub
  }

  @Override
  public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub
    String str = "";

    switch(event.sensor.getType()) {
      case Sensor.TYPE_ACCELEROMETER:
        gravity = event.values.clone();
        break;
      case Sensor.TYPE_MAGNETIC_FIELD:
        geomagnetic = event.values.clone();
        break;
      case Sensor.TYPE_ORIENTATION:
        orientation = event.values.clone();
        break;
    }
    if (gravity != null && geomagnetic != null && orientation != null) {
      // 回転行列を計算
      SensorManager.getRotationMatrix(inR, I, gravity, geomagnetic);
      // 端末の画面設定に合わせる(以下は, 縦表示で画面を上にした場合)
      SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, SensorManager.AXIS_Y, outR);
      // 方位角/傾きを取得
      SensorManager.getOrientation(outR, attitude);

      str = "1) 地磁気+加速度センサー"
        + "\n 方位角: " + String.format("%3.1f", Math.toDegrees(attitude[0]))
        + "\n 傾斜角: " + String.format("%3.1f", Math.toDegrees(attitude[1]))
        + "\n 回転角: " + String.format("%3.1f", Math.toDegrees(attitude[2]))
        + "\n\n2) 傾きセンサー"
        + "\n 方位角: " + String.format("%3.1f", (orientation[0] > 180.0 ? orientation[0]-360.0 : orientation[0]))
        + "\n 傾斜角: " + String.format("%3.1f", orientation[1])
        + "\n 回転角: " + String.format("%3.1f", orientation[2]);
      values.setText(str);
    }
  }
}
  • 動作例
端末:SHARP SH-03C / Android 2.2


TYPE_ORIENTATIONとは回転角の符号が反対となったので, 調査が必要.


コメントをかく


ユーザーIDでかく場合はこちら
「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu


逆引き(基礎編)

画面表示/操作(49)

フラグメント(1)

逆引き(応用編)

AD



管理人のみ編集できます