(1)实现SensorEventListener接口
接着上一篇的重力传感器(一)——监听数据,可以发现OrientationEventListener实际上就是监听了加速度传感器,并实现了SensorEventListener接口而已,相当于一个特例。
public OrientationEventListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mSensor != null) {
mSensorEventListener = new SensorEventListenerImpl();
}
}
public void enable() {
if (mSensor == null) {
Log.w(TAG, "Cannot detect sensors. Not enabled");
return;
}
if (mEnabled == false) {
if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
mEnabled = true;
}
}
class SensorEventListenerImpl implements SensorEventListener {
public void onSensorChanged(SensorEvent event) {}
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
}
(2)OrientationEventListener源码
//frameworks/base/core/java/android/view/OrientationEventListener.java
/**
* Helper class for receiving notifications from the SensorManager when
* the orientation of the device has changed.
*/
public abstract class OrientationEventListener {
private static final String TAG = "OrientationEventListener";
private static final boolean DEBUG = false;
private static final boolean localLOGV = false;
private int mOrientation = ORIENTATION_UNKNOWN;
private SensorManager mSensorManager;
private boolean mEnabled = false;
private int mRate;
private Sensor mSensor;
private SensorEventListener mSensorEventListener;
private OrientationListener mOldListener;
public static final int ORIENTATION_UNKNOWN = -1;
public OrientationEventListener(Context context) {
this(context, SensorManager.SENSOR_DELAY_NORMAL);
}
public OrientationEventListener(Context context, int rate) {
mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
mRate = rate;
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (mSensor != null) {
mSensorEventListener = new SensorEventListenerImpl();
}
}
void registerListener(OrientationListener lis) {
mOldListener = lis;
}
public void enable() {
if (mSensor == null) {
Log.w(TAG, "Cannot detect sensors. Not enabled");
return;
}
if (mEnabled == false) {
if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
mEnabled = true;
}
}
public void disable() {
if (mSensor == null) {
Log.w(TAG, "Cannot detect sensors. Invalid disable");
return;
}
if (mEnabled == true) {
if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");
mSensorManager.unregisterListener(mSensorEventListener);
mEnabled = false;
}
}
class SensorEventListenerImpl implements SensorEventListener {
private static final int _DATA_X = 0;
private static final int _DATA_Y = 1;
private static final int _DATA_Z = 2;
public void onSensorChanged(SensorEvent event) {
float[] values = event.values;
int orientation = ORIENTATION_UNKNOWN;
float X = -values[_DATA_X];
float Y = -values[_DATA_Y];
float Z = -values[_DATA_Z];
float magnitude = X*X + Y*Y;
// Don't trust the angle if the magnitude is small compared to the y value
if (magnitude * 4 >= Z*Z) {
float OneEightyOverPi = 57.29577957855f;
float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
orientation = 90 - (int)Math.round(angle);
// normalize to 0 - 359 range
while (orientation >= 360) {
orientation -= 360;
}
while (orientation < 0) {
orientation += 360;
}
}
if (mOldListener != null) {
mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values);
}
if (orientation != mOrientation) {
mOrientation = orientation;
onOrientationChanged(orientation);
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
public boolean canDetectOrientation() {
return mSensor != null;
}
/**
* Called when the orientation of the device has changed.
* orientation parameter is in degrees, ranging from 0 to 359.
*/
abstract public void onOrientationChanged(int orientation);
}
(3)可用的API
(4)Demo举例
监听手机旋转角度类:OrientationEventListener不只是判断屏幕旋转角度0,90,180,270 四个角度,还可以实时获取每一个角度的变化。
- 创建一个类继承OrientationEventListener;
- 开启和关闭监听:调用该类的 enable() 和 disable() 方法;
- 监测指定的屏幕旋转角度:onOrientationChanged的参数orientation是一个从0~359的变量;
OrientationEventListener mOrientationListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mOrientationListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
return; //手机平放时,检测不到有效的角度
}
//只检测是否有四个角度的改变
if (orientation > 350 || orientation < 10) { //0度
orientation = 0;
} else if (orientation > 80 && orientation < 100) { //90度
orientation = 90;
} else if (orientation > 170 && orientation < 190) { //180度
orientation = 180;
} else if (orientation > 260 && orientation < 280) { //270度
orientation = 270;
} else {
return;
}
}
};
if (mOrientationListener.canDetectOrientation()) {
mOrientationListener.enable();
} else {
mOrientationListener.disable();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mOrientationListener.disable();
}