今日はセンサーを使ってみました。
使ったセンサーは地磁気センサーと加速度センサー。
方位センサーっていうのがもともと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 件のコメント:
コメントを投稿