1. android 转屏
WindowOrientationListener.java
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//使用G-sensor.
rotation实现(详见:G-sensor与转屏:http://blog.csdn.net/jaylin2013/article/details/5698652):
系统启动windowManger.java时,它会启动phoneWindowManager.java,该类有一个内部类myOrientationListener扩展自windowOrientationListener.java。
windowOrientationListener.java是一个辅助类,当device的方向发生变化时,供windowManger.java调用,用来接收数据。
windowOrientationListener.java 内部在sensorManger.java中进行了注册,它回监听G-sensor传来的数据,即x,y,z方向的加速度,收到数据后经过转换处理,若满足Roate条件则调用
IwindowManager接口的实现类windowManagerService.java中的setRotation()方法实现转屏。
SensorManager通过polling的方式从设备得到Sensor数据, Sensor数据的结构定义在sensor.h里,
其中SensorManager只处理了 vector.v, vector.status, time三个域, 分发给已注册的对这些消息的监听者
比如第一项 vector.v包含x,y,z三个方向的信息值,就是由 WindowOrientataionLister注册的,
当 SensorManager获取到这三个值之后,会传递给 WindowOrientataionLister,后者代码位于:
frameworkd/base/core/java/android/view/WindowOrientationListener.java
WindowOrientataionLister接收到这三个值之后,会计算出设备对应的orientation,并且执行 onOrientationChanged函数进一步上传
WindowOrientataionLister是个纯虚类,如果在APK里需要控制方向,可以重载一个实例,
而Android的系统实例对应在 PhoneWindowManager.java里,名字为MyOrientationListener
frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java
如果需要旋转, MyOrientationListener则会调用以下代码进行窗口旋转:
mWindowManager.setRotation(rotation, false, mFancyRotationAnimation);
另外讲解G-sensor:http://blog.csdn.net/a345017062/article/details/6592527
OrientationEventListener类
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
------------------------------------------
// if Portrait change to LandScape
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
//if LandScape change to Portrait
else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
但以上方法有一个问题,就是必须设定一个默认的屏幕方向才可以,就是说我必须在AndroidManifest.xml中,配置一个默认的屏幕方向才可以,如添加以下配置:android:screenOrientation="portrait" ,不然就会失效,getRequestedOrientation这个方法得到的似乎也不一定是当前真实的屏幕方向,好像只是配置文件中的默认方向。
那如果我希望获取当前的屏幕方向呢?或者说我希望事实侦测当前转了多少角度该怎么做呢?其实还有另一种方法,可以通过OrientationEventListener来达到实时得到当前的屏幕转了多少角度,根据角度,你就可以来判断是横屏还是竖屏了呢,通过重写onOrientationChanged,你就可以得到角度值了,就可以做一些相应的处理了
public void onOrientationChanged(int orientation) {
// TODO Auto-generated method stub
if (OrientationEventListener.ORIENTATION_UNKNOWN != orientation) {
if (0 == orientation)
Log.e("MyNewLog", "Not change the Screen!!");
else if (90 == orientation)
Log.e("MyNewLog", "left side is at the top");
else if (180 == orientation)
Log.e("MyNewLog", "upside down");
else if (270 == orientation)
Log.e("MyNewLog", "right side is to the top");
}
}
转自:Android的屏幕方向转换
--------------------------------------
关于各个Sensor的认识:
G-Sensor
Android 加速度传感器的类型是 Sensor.TYPE_ACCELEROMETER
通过 android.hardware.SensorEvent 返回加速度传感器值。
加速度传感器返回值的单位是加速度的单位 m/s^2(米每二次方秒),有三个方向的值分别是
values[0]: x-axis 方向加速度
values[1]: y-axis 方向加速度
values[2]: z-axis 方向加速度
其中x,y,z方向的定义是以水平放置在的手机的右下脚为参照系坐标原点
x 方向就是手机的水平方向,右为正
y 方向就是手机的水平垂直方向,前为正
y 方向就是手机的空间垂直方向,天空的方向为正,地球的方向为负
需要注意的是:
由于地球固有的重力加速度g (值为9.8 m/s^2),
因此现实中实际加速度值应该是 z方向返回值 - 9.8 m/s^2.
比如你以 2 m/s^2 的加速度将手机抛起,这时z方向的返回值应该是 11.8 m/s^2.
反之若以手机以2 m/s^2 的加速度坠落,则z方向的返回值应该是 7.8 m/s^2.
x,y方向则没有上述限制。
--------------------------------------------
我们先简单介绍一下SmartPhone的三维坐标系:
X-axis:水平方向的,正数值代表右边,负数值代表右边;
Y-axis:垂直方向的,正数值代表上边,负数值代表下边;
Z-axis:指向手机屏幕的前段界面的外边。
下面为真机运行显示结果:
转自:http://www.linuxidc.com/Linux/2011-08/41926p2.htm
2.android magnetic
FrameWork层没有直接调用TYPE_MAGNETIC_FIELD的, 应该是应用直接去调用。
3. android orientation
Framework层还没有直接调用TYPE_ORIENTATION的,应该是应用直接去调用。