Skip to content

Instantly share code, notes, and snippets.

@smile0520
Created October 17, 2014 18:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smile0520/1425ed7cb064162fa20e to your computer and use it in GitHub Desktop.
Save smile0520/1425ed7cb064162fa20e to your computer and use it in GitHub Desktop.
Androidのセンサーを使って端末の向き(縦横)を判定する
package com.voidroider.sensorsample;
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 MainActivity extends Activity implements SensorEventListener {
/**
* 回転したと判定する際の閾値角度
*/
private static final int THRESHOLD_DEGREE = 60;
/**
* 縦から横に変化したと判定する際の角度
*/
private static final int VERTICAL_TO_HORIZONTAL_DEGREE = THRESHOLD_DEGREE;
/**
* 横から縦にに変化したと判定する際の角度
*/
private static final int HORIZONTAL_TO_VERTICAL_DEGREE = 90 - THRESHOLD_DEGREE;
/**
* 縦向きを表す定数
*/
private static final int ORIENTATION_VERTICAL = 0;
/**
* 横向きを表す定数
*/
private static final int ORIENTATION_HORIZONTAL = 1;
/**
* ラジアンを度に変換する際の定数
*/
protected final static double RAD2DEG = 180 / Math.PI;
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];
float[] orientationValues = new float[3];
float[] magneticValues = new float[3];
float[] accelerometerValues = new float[3];
private int mPreOrientation = -1;
SensorManager sensorManager;
TextView azimuthText;
TextView pitchText;
TextView rollText;
TextView orientationText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
initSensor();
}
public void onResume() {
super.onResume();
sensorManager.registerListener(
this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(
this,
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
SensorManager.SENSOR_DELAY_UI);
}
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
protected void findViews() {
azimuthText = (TextView) findViewById(R.id.azimuth);
pitchText = (TextView) findViewById(R.id.pitch);
rollText = (TextView) findViewById(R.id.roll);
orientationText = (TextView) findViewById(R.id.orientation);
}
protected void initSensor() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
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) {
SensorManager.getRotationMatrix(inR, I, accelerometerValues, magneticValues);
SensorManager.remapCoordinateSystem(inR, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
SensorManager.getOrientation(outR, orientationValues);
int azimuth = (int) (orientationValues[0] * RAD2DEG);
int pitch = (int) (orientationValues[1] * RAD2DEG);
int roll = (int) (orientationValues[2] * RAD2DEG);
// 以下、縦横判定処理
int absRoll = Math.abs(roll);
if (mPreOrientation == -1) {
mPreOrientation = absRoll < VERTICAL_TO_HORIZONTAL_DEGREE ?
ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
} else if (absRoll < 90) {
mPreOrientation = getOrientation(mPreOrientation, roll);
} else {
// プラマイ90度を超える場合は90度未満に置き換えて向きを反転させる。
int plusMinus = roll >= 0 ? 1 : -1;
roll = (absRoll - 90) * plusMinus;
int preOrientation = invertOrientation(mPreOrientation);
mPreOrientation = invertOrientation(getOrientation(preOrientation, roll));
}
// 表示の更新
azimuthText.setText(String.valueOf(azimuth));
pitchText.setText(String.valueOf(pitch));
rollText.setText(String.valueOf(roll));
orientationText.setText(mPreOrientation == ORIENTATION_VERTICAL ? "縦" : "横");
}
}
/**
* 与えられた端末の向きを反転させます。
*
* @param orientation 端末の向き({@link #ORIENTATION_HORIZONTAL} or {@link #ORIENTATION_VERTICAL} or -1)
* @return 反転した端末の向き({@link #ORIENTATION_HORIZONTAL} or {@link #ORIENTATION_VERTICAL} or -1)
*/
private int invertOrientation(int orientation) {
if (orientation == ORIENTATION_HORIZONTAL) {
return ORIENTATION_VERTICAL;
} else if (orientation == ORIENTATION_VERTICAL) {
return ORIENTATION_HORIZONTAL;
} else {
return -1;
}
}
/**
* 一つ前の端末の向きと現在の傾きを元に、現在の端末の向きを求めます
*
* @param preOrientation 一つ前の端末の向き({@link #ORIENTATION_HORIZONTAL} or {@link #ORIENTATION_VERTICAL} or -1)
* @param roll 傾き(90度未満)
* @return 現在の端末の向き({@link #ORIENTATION_HORIZONTAL} or {@link #ORIENTATION_VERTICAL} or -1)
*/
private int getOrientation(int preOrientation, int roll) {
int absRoll = Math.abs(roll);
if (preOrientation == ORIENTATION_VERTICAL) {
return (absRoll < VERTICAL_TO_HORIZONTAL_DEGREE) ?
ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
} else if (preOrientation == ORIENTATION_HORIZONTAL) {
return (absRoll < HORIZONTAL_TO_VERTICAL_DEGREE) ?
ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
} else {
return -1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment