【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

作者: 声网Agora 工程师 黄龙飞

前言
在日常生活中使用手机,通常都会遇到下面这两种场景。
场景一:
在使用手机看视频且设备开启屏幕自动旋转时,手机横着拿和竖着拿,所看到的效果会不一样。竖屏状态下的展示如下图(图1)所示,横屏状态下的展示如图2所示。

【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

图1.竖屏播放视频

【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

图2.横屏播放视频

场景二:
在使用的手机应用中,某些应用的某些界面会根据当前手机横竖屏的状态,展示不同的界面效果,方便大家使用。比如AgoraVideoCall中的会议界面,具体如图3 & 图4所示:

【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

图3.AgoraVideoCall会议界面竖屏展示

【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

图4.AgoraVideoCall会议界面横屏展示

上述中的两种场景,都是根据用户手持手机的方式及旋转动作自动识别出用户是想要横屏展示还是竖屏展示的。关于“手机如何根据用户的旋转动作而识别出用户意图"这个问题将会在下文中具体阐述。

加速度传感器原理
手机实现这一功能的核心部件是加速度传感器,在介绍加速度传感器之前,先了解一下传感器坐标系。

  • 传感器坐标系

【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用

图5.传感器坐标系(相对于设备)。

  • 加速度传感器

加速度传感器在Android横竖屏切换中的应用
加速度传感器在移动设备中的应用众多,本文主要介绍加速度传感器在Android系统中横竖屏切换的应用,其原理主要为:通过监听加速度传感器,实时获得X、Y、Z三个方向的加速度值;当4(X_X + Y_Y)>=Z*Z时,开始计算设备在X与Y平面上的旋转角度;最后根据旋转角度计算出设备的横竖屏状态。下面贴出主要代码。

/**

* 在onResume中,向SensorManager注册监听加速度传感器

*/

@Override

protected void onResume() {

super.onResume();

orientationListener = new OrientationListener(this);

orientationListener.enable();

}

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 {

private static final int _DATA_X = 0;

private static final int _DATA_Y = 1;

private static final int _DATA_Z = 2;

/**

** 通过X、Y、Z三个方向的加速度值的变化,计算出设备旋转的角度。

**/

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 class OrientationListener extends OrientationEventListener {

private int degree = 0;//旋转角度

private int mOrientation = 0;//2—横屏 1-竖屏,0-未知

public OrientationListener(Context context) {

super(context);

}

/**

* 根据旋转的角度,得出设备横竖屏状态

**/

@Override

public void onOrientationChanged(int orientation) {

degree = orientation;

if (degree > 0 && degree < 45) {

mOrientation = 1;

} else if (degree > 45 && degree < 135) {

mOrientation = 2;

} else if (degree > 135 && degree < 225) {

mOrientation = 1;

} else if (degree > 225 && degree < 315) {

mOrientation = 2;

} else if (degree > 315 && degree < 360) {

mOrientation = 1;

}

if (mOrientation == 2) {

Log.i("OrientationListener ", "横屏");

} else if (mOrientation == 1) {

Log.i("OrientationListener ", "竖屏");

}

}

}

特别说明:Math.atan2(-Y, X) 是计算从原点(0,0)到(x,y)点的线段与x轴正方向之间的平面角度(弧度值),
float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi得到的是原点(0,0)到(x,y)点的线段与x轴正方向之间的角度,90 - (int)Math.round(angle)为设备旋转的角度。

实战演练
本节实现一个简易的打高尔夫球游戏,练习一下加速度传感器的运用。该游戏为多人游戏,游戏规则为:参与者通过摇晃手机控制高尔夫球的移动,当高尔夫球落到洞中则计1分,否则不计分,每人操作3次,得分最高者获胜。游戏实现原理是根据加速度传感器获得设备旋转角度,实时计算并更新高尔夫球的位置,根据高尔夫球的位置与洞的重合度,判断高尔夫球是否落入洞中。落入洞中则得分,否则,不计分。游戏具体实现见附件,演示如下。

链接: https://pan.baidu.com/s/1Kas3kL0fdaXbygGA--l7JQ 2 提取码: 87nh
链接: https://pan.baidu.com/s/1yXNbbI3QhYG3BMZsyG2PSw 1 提取码: 8uaz

扩展
大多数移动设备,除了上面介绍的加速度传感器外,还有很多内置传感器,比如:重力传感器、旋转矢量传感器、屏幕方向传感器、温度传感器、光传感器、压力传感器等(如需了解详细信息,请参阅传感器)。开发者可以根据这些传感器,实现许多非常智能的功能。比如:

  • 通过光线传感器,自动调节屏幕的亮度,保护用户的眼睛
  • 通过加速度传感器,实现计步器和运动检测功能
  • 通过湿度传感器和温度传感器,计算露点和绝对湿度
  • 通过GPS,实现导航功能

参考文献:

  • https://developer.android.com/guide/topics/sensors/sensors_motion?hl=zh-cn 1
  • https://developer.android.com/guide/topics/sensors/sensors_overview?hl=zh-cn
  • https://github.com/googlearchive/android-AccelerometerPlay
  • https://v.qq.com/x/page/t050708r6ea.html
  • https://baike.baidu.com/item/重力感应器?fromtitle=重力传感器&fromid=3623984

附件
AccelerometerPlay.zip (5.0 KB)

以上是 【安卓】自动切换横竖屏幕——手机加速度传感器在Android横竖屏切换中的应用 的全部内容, 来源链接: utcz.com/a/97632.html

回到顶部