今日はセンサーを使ってみました。
使ったセンサーは地磁気センサーと加速度センサー。
方位センサーっていうのがもともとTYPE_ORIENTATIONというのであったみたいなんですが今は非推奨。
ですのでこの2つのセンサーを利用して方位を取得します。
まずセンサーを利用する準備。
public class CompassTestActivity extends Activity implements SensorEventListener { private SensorManager sensor; /** lifecycle */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); requestWindowFeature(Window.FEATURE_NO_TITLE); sensor = (SensorManager)getSystemService(SENSOR_SERVICE); setContentView(R.layout.main); } @Override public void onResume() { super.onResume(); // センサーイベントの登録 sensor.registerListener(this, sensor.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI); sensor.registerListener(this, sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); } @Override public void onPause() { // センサーイベントを削除 sensor.unregisterListener(this); super.onPause(); } }
sensor.registerListenerの引数は
- イベントリスナーのオブジェクト
- センサーの種類
- データ取得の頻度
といったかんじになります。
頻度をSENSOR_DELAY_UIとしてますが他にもSENSOR_DELAY_NORMALとかSENSOR_DELAY_GAMEなどいくつかありますのでつくるアプリ合わせて設定をします。
センサーは(センサーに限った話しではないですが)アプリがバックグランドになったときも動き続けますのでonResumeでイベント登録し、onPauseでイベント削除します。
つぎにセンサーイベントの実装です。
/** SensorEventListener */ @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onSensorChanged(SensorEvent event) { if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) return; switch (event.sensor.getType()) { case Sensor.TYPE_MAGNETIC_FIELD: // 地磁気センサ magneticValues = event.values.clone(); break; case Sensor.TYPE_ACCELEROMETER: // 加速度センサ accelerometerValues = event.values.clone(); break; } if (magneticValues != null && accelerometerValues != null) { float[] rotationMatrix = new float[MATRIX_SIZE]; float[] inclinationMatrix = new float[MATRIX_SIZE]; float[] remapedMatrix = new float[MATRIX_SIZE]; float[] orientationValues = new float[DIMENSION]; // 加速度センサと地磁気センサから回転行列を取得 SensorManager.getRotationMatrix(rotationMatrix, inclinationMatrix, accelerometerValues, magneticValues); SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapedMatrix); SensorManager.getOrientation(remapedMatrix, orientationValues); // 方位を取得する int orientDegrees = toOrientationDegrees(orientationValues[0]); String orientString = toOrientationString(orientationValues[0]); Log.d(TAG, "orientDegrees = " + orientDegrees + " , orientString = " + orientString); } } /** * 方位の角度に変換する * @param angrad * @return */ private int toOrientationDegrees(float angrad) { return (int)Math.floor(angrad >= 0 ? Math.toDegrees(angrad) : 360 + Math.toDegrees(angrad)); } /** * 方位の文字列に変換する * @param angrad * @return */ private String toOrientationString(float angrad) { double[] orientation_range = { - (Math.PI * 3 / 4), // 南 - (Math.PI * 1 / 4), // 西 + (Math.PI * 1 / 4), // 北 + (Math.PI * 3 / 4), // 東 }; String[] orientation_string = { "south", "west", "north", "east", }; for (int i = 0; i < orientation_range.length; i++) { if (angrad < orientation_range[i]) { return orientation_string[i]; } } return orientation_string[0]; }
まだまだわからないことがありますがセンサーイベントには、onAccuracyChangedとonSensorChangedがあります。
- onAccuracyChanged・・・精度?に変化があった場合
- onSensorChanged・・・値に変化があった場合
ここでは値に変化があった場合に処理するようにしています。
中身はあんまり詳しく説明できないので参考にしたサイト
このセンサーとカメラ機能を使っていま向いてる方位(4方位しかないですが)を表示するだけのものを作ってみました。
ただ、Galaxy Nexusでは動きませんでした。。。なんでだ。。。
動作はAQUOS PHONE f SH-13Cで確認しました
0 件のコメント:
コメントを投稿